/**
 * Go-No-Go GD-4 + RPA probe 3/3 验收（task-117 + task-134）
 * 用法：tsx scripts/go-no-go-check.ts [--mock]
 */
import "dotenv/config";
import {
  computeRates,
  type MetricsCounters,
} from "@/modules/metrics/collector";
import { METRIC_COUNTER } from "@/lib/constants/metrics";
import { validateProbeItems } from "@/lib/rpa/probe-validation";
import { executeProbeQuote } from "@/lib/rpa/run-probe";

const THRESHOLDS = {
  api_success_rate: 99.5,
  rpa_success_rate: 85,
  realtime_rate: 90,
  cache_hit_rate: 90,
  p95_latency_ms: 30_000,
  probe_success_count: 3,
} as const;

const PROBE_ROUNDS = 3;

type CheckResult = {
  name: string;
  value: number | string;
  threshold: number | string;
  pass: boolean;
  operator: ">=" | "<" | "—";
  skipped?: boolean;
};

function buildMockCounters(): MetricsCounters {
  return {
    [METRIC_COUNTER.POST_TOTAL]: 1000,
    [METRIC_COUNTER.POST_DONE]: 996,
    [METRIC_COUNTER.CACHE_HIT_L1]: 200,
    [METRIC_COUNTER.CACHE_HIT_L2]: 720,
    [METRIC_COUNTER.RPA_TRIGGERED]: 100,
    [METRIC_COUNTER.RPA_DONE]: 88,
    [METRIC_COUNTER.DONE_TOTAL]: 996,
    [METRIC_COUNTER.DONE_REALTIME]: 910,
  };
}

function isMockMode(): boolean {
  return (
    process.argv.includes("--mock") || process.env.RPA_MOCK_MODE === "true"
  );
}

async function loadSnapshot(): Promise<{
  rates: ReturnType<typeof computeRates>;
  p95: number;
}> {
  if (process.argv.includes("--mock")) {
    const counters = buildMockCounters();
    return { rates: computeRates(counters), p95: 12_000 };
  }

  const { getMetricsSnapshot } = await import("@/modules/metrics/collector");
  const snapshot = await getMetricsSnapshot();
  return {
    rates: {
      api_success_rate: snapshot.api_success_rate,
      rpa_success_rate: snapshot.rpa_success_rate,
      realtime_rate: snapshot.realtime_rate,
      cache_hit_rate: snapshot.cache_hit_rate,
    },
    p95: snapshot.p95_latency_ms,
  };
}

function runMetricChecks(
  rates: ReturnType<typeof computeRates>,
  p95: number,
): CheckResult[] {
  return [
    {
      name: "API success rate",
      value: rates.api_success_rate,
      threshold: THRESHOLDS.api_success_rate,
      pass: rates.api_success_rate >= THRESHOLDS.api_success_rate,
      operator: ">=",
    },
    {
      name: "RPA success rate",
      value: rates.rpa_success_rate,
      threshold: THRESHOLDS.rpa_success_rate,
      pass: rates.rpa_success_rate >= THRESHOLDS.rpa_success_rate,
      operator: ">=",
    },
    {
      name: "Realtime rate",
      value: rates.realtime_rate,
      threshold: THRESHOLDS.realtime_rate,
      pass: rates.realtime_rate >= THRESHOLDS.realtime_rate,
      operator: ">=",
    },
    {
      name: "Cache hit rate",
      value: rates.cache_hit_rate,
      threshold: THRESHOLDS.cache_hit_rate,
      pass: rates.cache_hit_rate >= THRESHOLDS.cache_hit_rate,
      operator: ">=",
    },
    {
      name: "P95 latency (ms)",
      value: p95,
      threshold: THRESHOLDS.p95_latency_ms,
      pass: p95 < THRESHOLDS.p95_latency_ms,
      operator: "<",
    },
  ];
}

/** PRD §12.7 CHG-P09：真实 env 下 probe 连续 3 次 exit 0 */
async function runProbeGate(): Promise<CheckResult> {
  if (isMockMode()) {
    return {
      name: "RPA probe 3/3",
      value: "跳过",
      threshold: PROBE_ROUNDS,
      pass: true,
      operator: "—",
      skipped: true,
    };
  }

  let success = 0;
  for (let round = 1; round <= PROBE_ROUNDS; round++) {
    try {
      console.log(`[go-no-go] probe 第 ${round}/${PROBE_ROUNDS} 次…`);
      const result = await executeProbeQuote();
      const validation = validateProbeItems(result.items);
      if (validation.ok) {
        success += 1;
      } else {
        console.error(`[go-no-go] probe 失败: ${validation.message}`);
      }
    } catch (error) {
      console.error(`[go-no-go] probe 异常:`, error);
    }
  }

  return {
    name: "RPA probe 3/3",
    value: success,
    threshold: THRESHOLDS.probe_success_count,
    pass: success === PROBE_ROUNDS,
    operator: ">=",
  };
}

async function main(): Promise<void> {
  const { rates, p95 } = await loadSnapshot();
  const metricChecks = runMetricChecks(rates, p95);
  const probeCheck = await runProbeGate();
  const checks = [...metricChecks, probeCheck];
  const required = checks.filter((c) => !c.skipped);
  const allPass = required.every((c) => c.pass);

  console.log("=== Go-No-Go 验收 ===");
  for (const check of checks) {
    if (check.skipped) {
      console.log(`[SKIP] ${check.name}: mock 模式跳过 probe 门禁`);
      continue;
    }
    const status = check.pass ? "PASS" : "FAIL";
    console.log(
      `[${status}] ${check.name}: ${check.value} (需 ${check.operator} ${check.threshold})`,
    );
  }
  console.log(`\n总体判定: ${allPass ? "PASS" : "FAIL"}`);

  if (!allPass) {
    process.exit(1);
  }
}

main().catch((error) => {
  console.error("[go-no-go] 执行失败:", error);
  process.exit(1);
});
