/*
  Host guard for every UI-driving (Playwright) admin script.

  The REST write path is already structurally safe: `dol-write.sh` refuses any
  host that is not the sandbox (ADR-0003). The UI path had no equivalent — and
  `test/.env` ships DOLIBARR_ADDRESS pointing at PRODUCTION, so a script run
  with the ambient environment would drive the real ERP. This module closes
  that gap: an admin script calls `assertSandbox()` before its first click,
  and dies otherwise.

  Production changes are never made by a script. They are rehearsed here, then
  applied by the operator through the human-gated path.
*/

/** Hosts an admin script is allowed to drive. Sandbox only, by design. */
const ALLOWED_HOST_PATTERN = /^erp-sandbox\./i;

export class UnsafeTargetError extends Error {}

/**
 * Resolve the target address and refuse anything that is not the sandbox.
 * Pass an explicit address, or let it read DOLIBARR_ADDRESS from the env.
 */
export function assertSandbox(address?: string): string {
  const target = address ?? Deno.env.get("DOLIBARR_ADDRESS") ?? "";
  if (!target) {
    throw new UnsafeTargetError(
      "guard: no target address (pass one, or set DOLIBARR_ADDRESS)",
    );
  }

  let host: string;
  try {
    host = new URL(target).host;
  } catch {
    throw new UnsafeTargetError(`guard: not a valid URL: ${target}`);
  }

  if (!ALLOWED_HOST_PATTERN.test(host)) {
    // Production opt-in: deliberate, loud, and per-run. The operator must name
    // the exact host AND type the confirmation phrase, so nothing reaches prod
    // by inheriting an ambient variable — the same posture the promote flow
    // takes with DOLIBARR_PROD_WRITE_KEY / ARCO_PROMOTE_CONFIRM.
    const allowProd = Deno.env.get("ARCO_ALLOW_PRODUCTION") ?? "";
    const confirm = Deno.env.get("ARCO_PROD_CONFIRM") ?? "";
    if (allowProd === host && confirm === "I-UNDERSTAND-THIS-WRITES-PROD") {
      console.warn(
        `\n*** PRODUCTION TARGET: ${host} — explicit opt-in accepted. ***\n` +
          "    Every write below hits the real ledger and cannot be undone.\n",
      );
      return target;
    }
    throw new UnsafeTargetError(
      `REFUSED: '${host}' is not the sandbox.\n` +
        "UI admin scripts may only drive erp-sandbox.*; production is changed " +
        "by the operator through the human-gated path, never by a script.\n" +
        "Override the ambient env explicitly, e.g.\n" +
        "  DOLIBARR_ADDRESS=https://erp-sandbox.arcodange.lab deno run ...\n" +
        "To target production on purpose, set BOTH:\n" +
        `  ARCO_ALLOW_PRODUCTION=${host} ARCO_PROD_CONFIRM=I-UNDERSTAND-THIS-WRITES-PROD`,
    );
  }
  return target;
}

export default { assertSandbox, UnsafeTargetError };
