/**
 * The ONE base-app touch-point — PLAN_RELAY_AGENT T17 (INDEX §0, EXPLORE §3 "Zero code change").
 * APPENDS `https://<subdomain>.<zone>.<domain>` to the base app's ALLOWED_ORIGINS env (idempotent),
 * as CONFIG — NO `src/` code edit. AUGMENTS, never weakens, the Origin/CSWSH check: existing
 * origins are always preserved (EXPLORE §3 "do not weaken the check").
 *
 * PLAN_NATIVE_TUNNEL S2: the DNS zone label is PARAMETERIZED. Relay callers keep the historical
 * `term` zone (default), while native-tunnel hosts pass `terminal` so the base app trusts
 * `https://<name>.terminal.<domain>`. The default is preserved so existing callers/tests are
 * unaffected — the zone is opt-in per call, never hard-flipped.
 */
import { existsSync, readFileSync, writeFileSync } from 'node:fs'

export interface OriginFsDeps {
  exists(path: string): boolean
  read(path: string): string
  write(path: string, content: string): void
}

const defaultFs: OriginFsDeps = {
  exists: existsSync,
  read: (p) => readFileSync(p, 'utf8'),
  write: (p, c) => writeFileSync(p, c),
}

/** Default DNS zone label (relay hosts). Native-tunnel hosts pass `terminal`. */
export const DEFAULT_ORIGIN_ZONE = 'term'

const KEY = 'ALLOWED_ORIGINS'

/** Compose the subdomain origin the base app must trust: `https://<subdomain>.<zone>.<domain>`. */
export function subdomainOrigin(
  subdomain: string,
  domain: string,
  zone: string = DEFAULT_ORIGIN_ZONE,
): string {
  return `https://${subdomain}.${zone}.${domain}`
}

/**
 * Merge `origin` into a comma-separated ALLOWED_ORIGINS value, preserving every existing origin and
 * de-duplicating. Returns the merged CSV; never removes an origin. Pure/immutable.
 */
export function mergeOrigins(current: string | undefined, origin: string): string {
  const origins = (current ?? '')
    .split(',')
    .map((s) => s.trim())
    .filter((s) => s.length > 0)
  if (origins.includes(origin)) return origins.join(',')
  return [...origins, origin].join(',')
}

function upsertOriginLine(content: string, origin: string): string {
  const lines = content.length === 0 ? [] : content.split('\n')
  let found = false
  const next = lines.map((line) => {
    if (!line.startsWith(`${KEY}=`)) return line
    found = true
    return `${KEY}=${mergeOrigins(line.slice(KEY.length + 1), origin)}`
  })
  if (!found) next.push(`${KEY}=${origin}`)
  return next.join('\n')
}

/**
 * Idempotently append the subdomain origin to ALLOWED_ORIGINS in `baseAppEnvPath`. Never removes an
 * existing origin. Creates the file/line if absent. `zone` selects the DNS zone label (default
 * preserves relay callers).
 */
export function ensureAllowedOrigin(
  baseAppEnvPath: string,
  subdomain: string,
  domain: string,
  fs: OriginFsDeps = defaultFs,
  zone: string = DEFAULT_ORIGIN_ZONE,
): void {
  const origin = subdomainOrigin(subdomain, domain, zone)
  const existing = fs.exists(baseAppEnvPath) ? fs.read(baseAppEnvPath) : ''
  const updated = upsertOriginLine(existing, origin)
  fs.write(baseAppEnvPath, updated.endsWith('\n') ? updated : `${updated}\n`)
}
