#!/usr/bin/env node
import { createHash } from 'node:crypto';
import { lstat, mkdir, readFile, readdir, writeFile } from 'node:fs/promises';
import { dirname, resolve } from 'node:path';

const shaPattern = /^[0-9a-f]{40}$/;
const digestPattern = /^sha256:[0-9a-f]{64}$/;
const hashPattern = /^[0-9a-f]{64}$/;
const unsafeKeyPattern = /(password|secret|token|credential|authorization|api.?key|access.?key|private.?key|connection.?string|database.?url|proxy)/i;

function parseArgs(argv) {
  const command = argv.shift();
  const values = {};
  while (argv.length > 0) {
    const key = argv.shift();
    if (!key?.startsWith('--') || argv.length === 0) throw new Error('invalid arguments');
    values[key.slice(2)] = argv.shift();
  }
  return { command, values };
}

async function regularJSON(path) {
  const absolute = resolve(path);
  const info = await lstat(absolute);
  if (!info.isFile() || info.isSymbolicLink()) throw new Error(`${path} must be a regular non-symlink file`);
  return JSON.parse(await readFile(absolute, 'utf8'));
}

function assertSecretSafe(value, path = '$') {
  if (Array.isArray(value)) {
    value.forEach((item, index) => assertSecretSafe(item, `${path}[${index}]`));
    return;
  }
  if (value && typeof value === 'object') {
    for (const [key, nested] of Object.entries(value)) {
      if (key !== 'secretSafe' && unsafeKeyPattern.test(key)) {
        throw new Error(`unsafe report key at ${path}.${key}`);
      }
      assertSecretSafe(nested, `${path}.${key}`);
    }
    return;
  }
  if (typeof value === 'string' && /(?:postgres(?:ql)?|https?):\/\/[^\s]+/i.test(value)) {
    throw new Error(`URL-like value is forbidden at ${path}`);
  }
}

function validate(report) {
  if (report.schemaVersion !== 'acceptance-report/v1' || report.secretSafe !== true) {
    throw new Error('unsupported or non-secret-safe acceptance report');
  }
  if (!report.runId || !shaPattern.test(report.release?.sourceSha ?? '') ||
      !digestPattern.test(report.release?.apiImageDigest ?? '') ||
      !digestPattern.test(report.release?.workerImageDigest ?? '') ||
      !shaPattern.test(report.snapshot?.sourceReleaseSha ?? '') ||
      !hashPattern.test(report.snapshot?.configHash ?? '') ||
      !hashPattern.test(report.snapshot?.sha256 ?? '')) {
    throw new Error('acceptance report identity fields are invalid');
  }
  if (!report.stages || !Array.isArray(report.gates) ||
      report.promotion?.requiresManualConfirmation !== true ||
      !['validation', 'live', 'not-applicable'].includes(report.promotion?.trafficMode)) {
    throw new Error('acceptance report stages, gates, or promotion are invalid');
  }
  for (const [name, stage] of Object.entries(report.stages)) {
    if (!['passed', 'failed', 'not-run'].includes(stage?.status)) {
      throw new Error(`invalid stage status for ${name}`);
    }
  }
  assertSecretSafe(report);
}

async function loadReports(directory) {
  const entries = (await readdir(resolve(directory), { withFileTypes: true }))
    .filter((entry) => entry.isFile() && entry.name.endsWith('.json'))
    .map((entry) => entry.name)
    .sort();
  const reports = [];
  for (const name of entries) {
    const report = await regularJSON(resolve(directory, name));
    if (report.schemaVersion === 'acceptance-load-report/v1') {
      if (report.secretSafe !== true) throw new Error(`load report ${name} is not secret-safe`);
      reports.push({
        file: name,
        profile: report.profile,
        passed: report.passed,
        phases: report.phases,
        startedAt: report.startedAt,
        finishedAt: report.finishedAt
      });
    }
  }
  return reports;
}

async function buildLocal(values) {
  for (const key of ['runtime', 'snapshot', 'reports', 'artifact', 'output']) {
    if (!values[key]) throw new Error(`--${key} is required`);
  }
  const runtime = await regularJSON(values.runtime);
  const snapshot = await regularJSON(values.snapshot);
  const artifact = await regularJSON(values.artifact);
  const loads = await loadReports(values.reports);
  if (runtime.schemaVersion !== 'acceptance-runtime/v1' ||
      snapshot.schemaVersion !== 'acceptance-snapshot/v1' ||
      artifact.schemaVersion !== 'acceptance-artifact-smoke/v1') {
    throw new Error('local report inputs have incompatible schema versions');
  }
  if (runtime.releaseSha !== artifact.releaseSha ||
      artifact.apiImageDigest !== values['api-digest'] ||
      runtime.snapshotConfigHash !== snapshot.source.configHash ||
      runtime.snapshotSha256 !== snapshot.snapshotSha256) {
    throw new Error('local report CAS identity mismatch');
  }
  const localPassed = loads.length > 0 && loads.every((item) => item.passed === true);
  const gates = [
    { id: 'local_load_reports', passed: localPassed, detail: `${loads.length} load reports` },
    { id: 'amd64_artifact_smoke', passed: artifact.passed === true }
  ];
  const report = {
    schemaVersion: 'acceptance-report/v1',
    runId: runtime.runId,
    release: {
      sourceSha: artifact.releaseSha,
      apiImageDigest: artifact.apiImageDigest,
      workerImageDigest: artifact.apiImageDigest
    },
    snapshot: {
      sourceReleaseSha: snapshot.source.releaseSha,
      configHash: snapshot.source.configHash,
      sha256: snapshot.snapshotSha256
    },
    stages: {
      localNative: { status: localPassed ? 'passed' : 'failed', loadReports: loads },
      amd64Artifact: { status: artifact.passed ? 'passed' : 'failed', ...artifact },
      onlineSimulation: { status: 'not-run' },
      realCanary: { status: 'not-run' }
    },
    certifiedProfile: values['certified-profile'] ? {
      name: values['certified-profile'],
      source: 'local-candidate-only'
    } : null,
    gates,
    promotion: {
      ready: false,
      requiresManualConfirmation: true,
      trafficMode: 'not-applicable'
    },
    createdAt: new Date().toISOString(),
    secretSafe: true
  };
  validate(report);
  await mkdir(dirname(resolve(values.output)), { recursive: true, mode: 0o700 });
  await writeFile(resolve(values.output), `${JSON.stringify(report, null, 2)}\n`, { mode: 0o600 });
  process.stdout.write(`acceptance_report_local=PASS sha256=${createHash('sha256').update(JSON.stringify(report)).digest('hex')}\n`);
}

async function buildLocalPartial(values) {
  for (const key of ['runtime', 'snapshot', 'reports', 'output', 'failure-phase']) {
    if (!values[key]) throw new Error(`--${key} is required`);
  }
  const runtime = await regularJSON(values.runtime);
  const snapshot = await regularJSON(values.snapshot);
  const loads = await loadReports(values.reports);
  if (runtime.schemaVersion !== 'acceptance-runtime/v1' ||
      snapshot.schemaVersion !== 'acceptance-snapshot/v1' ||
      !shaPattern.test(runtime.releaseSha ?? '') ||
      !digestPattern.test(runtime.apiImageDigest ?? '') ||
      !digestPattern.test(runtime.workerImageDigest ?? '') ||
      runtime.snapshotConfigHash !== snapshot.source.configHash ||
      runtime.snapshotSha256 !== snapshot.snapshotSha256) {
    throw new Error('partial local report inputs have incompatible CAS identity');
  }
  const completedLoadsPassed = loads.every((item) => item.passed === true);
  const report = {
    schemaVersion: 'acceptance-report/v1',
    runId: runtime.runId,
    release: {
      sourceSha: runtime.releaseSha,
      apiImageDigest: runtime.apiImageDigest,
      workerImageDigest: runtime.workerImageDigest
    },
    snapshot: {
      sourceReleaseSha: snapshot.source.releaseSha,
      configHash: snapshot.source.configHash,
      sha256: snapshot.snapshotSha256
    },
    stages: {
      localNative: {
        status: 'failed',
        failurePhase: values['failure-phase'],
        completedLoadReportsPassed: completedLoadsPassed,
        loadReports: loads
      },
      amd64Artifact: { status: 'not-run' },
      onlineSimulation: { status: 'not-run' },
      realCanary: { status: 'not-run' }
    },
    certifiedProfile: values['certified-profile'] ? {
      name: values['certified-profile'],
      source: 'last-local-stable-candidate'
    } : null,
    gates: [
      {
        id: 'local_execution_complete',
        passed: false,
        detail: `stopped during ${values['failure-phase']}`
      },
      {
        id: 'completed_load_reports',
        passed: completedLoadsPassed,
        detail: `${loads.length} load reports`
      }
    ],
    promotion: {
      ready: false,
      requiresManualConfirmation: true,
      trafficMode: 'not-applicable'
    },
    createdAt: new Date().toISOString(),
    secretSafe: true
  };
  validate(report);
  await mkdir(dirname(resolve(values.output)), { recursive: true, mode: 0o700 });
  await writeFile(resolve(values.output), `${JSON.stringify(report, null, 2)}\n`, { mode: 0o600 });
  process.stdout.write('acceptance_report_local_partial=PASS\n');
}

async function mergeProduction(values) {
  for (const key of ['local-report', 'production-summary', 'output']) {
    if (!values[key]) throw new Error(`--${key} is required`);
  }
  const local = await regularJSON(values['local-report']);
  const production = await regularJSON(values['production-summary']);
  validate(local);
  if (local.release.sourceSha !== production.releaseSha ||
      local.release.apiImageDigest !== production.apiImageDigest ||
      local.snapshot.configHash !== production.snapshotConfigHash ||
      local.snapshot.sha256 !== production.snapshotSha256) {
    throw new Error('production summary does not match local acceptance CAS fields');
  }
  local.stages.onlineSimulation = {
    status: production.passed === true ? 'passed' : 'failed',
    stableCapacityProfile: production.stableCapacityProfile,
    tasks: production.tasks,
    geminiTasks: production.geminiTasks,
    videoTasks: production.videoTasks
  };
  local.stages.realCanary = {
    status: production.realCanaryPassed === true ? 'passed' : 'failed'
  };
  local.certifiedProfile = production.certifiedProfile ?? local.certifiedProfile;
  local.gates.push(...(production.gates ?? []));
  local.promotion = {
    ready: production.passed === true && production.realCanaryPassed === true &&
      local.gates.every((gate) => gate.passed === true),
    requiresManualConfirmation: true,
    trafficMode: 'validation'
  };
  local.createdAt = new Date().toISOString();
  validate(local);
  await mkdir(dirname(resolve(values.output)), { recursive: true, mode: 0o700 });
  await writeFile(resolve(values.output), `${JSON.stringify(local, null, 2)}\n`, { mode: 0o600 });
  process.stdout.write(`acceptance_report_production=PASS promotion_ready=${local.promotion.ready}\n`);
}

const { command, values } = parseArgs(process.argv.slice(2));
if (command === 'validate') {
  const report = await regularJSON(values.input ?? '');
  validate(report);
  process.stdout.write('acceptance_report_validate=PASS\n');
} else if (command === 'build-local') {
  await buildLocal(values);
} else if (command === 'build-local-partial') {
  await buildLocalPartial(values);
} else if (command === 'merge-production') {
  await mergeProduction(values);
} else if (command === 'mark-promoted') {
  const input = values.input ?? '';
  const output = values.output ?? input;
  const report = await regularJSON(input);
  validate(report);
  if (report.promotion.ready !== true || report.promotion.trafficMode !== 'validation') {
    throw new Error('only a ready validation report can be marked promoted');
  }
  report.promotion.trafficMode = 'live';
  report.promotion.promotedAt = new Date().toISOString();
  await writeFile(resolve(output), `${JSON.stringify(report, null, 2)}\n`, { mode: 0o600 });
  process.stdout.write('acceptance_report_promoted=PASS\n');
} else if (command === 'attach-monitor') {
  const input = values.input ?? '';
  const output = values.output ?? input;
  const report = await regularJSON(input);
  const monitor = await regularJSON(values.monitor ?? '');
  validate(report);
  if (monitor.schemaVersion !== 'acceptance-monitor-report/v1' ||
      monitor.runId !== report.runId || monitor.releaseSha !== report.release.sourceSha ||
      monitor.secretSafe !== true) {
    throw new Error('monitor report does not match overall acceptance report');
  }
  report.stages.postPromotionMonitor = {
    status: monitor.passed === true ? 'passed' : 'failed',
    startedAt: monitor.startedAt,
    finishedAt: monitor.finishedAt,
    samples: monitor.samples,
    failureGateId: monitor.failureGateId
  };
  if (monitor.passed !== true) {
    report.promotion.ready = false;
    report.promotion.trafficMode = 'validation';
  }
  await writeFile(resolve(output), `${JSON.stringify(report, null, 2)}\n`, { mode: 0o600 });
  process.stdout.write(`acceptance_report_monitor=PASS monitor_passed=${monitor.passed === true}\n`);
} else {
  throw new Error('usage: report.mjs {validate|build-local|build-local-partial|merge-production|mark-promoted|attach-monitor} [options]');
}
