#!/usr/bin/env node

"use strict";

/**
 * gate-check.js — Validate phase prerequisites before orchestrator execution.
 *
 * Usage:
 *   node gate-check.js <feature> <required-step> [--rigor lite|standard|strict] [--force] [--reason "..."]
 *
 * Checks that the required step is done with a passing gate verdict.
 * Applies rigor-based override policy when prerequisites are not met.
 *
 * Exit codes:
 *   0 = passed (or forced override allowed)
 *   1 = blocked
 */

const path = require("path");
const {
  readLifecycle,
  writeLifecycle,
  withLifecycleLock,
  toSlug,
  STEPS,
} = require("./update-lifecycle");

const PASSING_VERDICTS = ["PASS", "CONDITIONAL"];
const VALID_RIGOR = ["lite", "standard", "strict"];

function parseFlag(args, flag) {
  const idx = args.indexOf(flag);
  if (idx === -1 || idx + 1 >= args.length) return null;
  return args[idx + 1];
}

/**
 * Run the gate check.
 * @param {string} featureSlug
 * @param {string} requiredStep - The step that must be complete
 * @param {{rigor: string, force: boolean, reason: string|null}} opts
 * @returns {{passed: boolean, lifecycle_status: string, gate_verdict: string|null, override_allowed: boolean, blocking_reason: string|null}}
 */
function gateCheck(featureSlug, requiredStep, opts = {}) {
  const { rigor = "standard", force = false, reason = null } = opts;
  const slug = toSlug(featureSlug);

  const data = readLifecycle();
  if (!data.features[slug]) {
    console.error(`Feature not found: ${slug}`);
    process.exit(1);
  }

  const stepData = data.features[slug].steps[requiredStep] || {};
  const status = stepData.status || "pending";
  const verdict = stepData.gate_verdict || null;

  const statusOk = status === "done";
  const verdictOk = PASSING_VERDICTS.includes(verdict);

  if (statusOk && verdictOk) {
    return {
      passed: true,
      lifecycle_status: status,
      gate_verdict: verdict,
      override_allowed: false,
      blocking_reason: null,
    };
  }

  // Build blocking reason
  const parts = [];
  if (!statusOk)
    parts.push(`step '${requiredStep}' is not done (status: ${status})`);
  if (!verdictOk)
    parts.push(`gate verdict is not passing (verdict: ${verdict})`);
  const blockingReason = parts.join("; ");

  // Apply rigor policy
  const overrideAllowed = rigor !== "strict";

  if (force && overrideAllowed) {
    // Record the forced override in lifecycle
    withLifecycleLock(() => {
      const fresh = readLifecycle();
      const currentStep =
        STEPS[STEPS.indexOf(requiredStep) + 1] || requiredStep;
      const currentStepData = fresh.features[slug].steps[currentStep] || {
        status: "pending",
      };
      currentStepData.forced_at = new Date().toISOString();
      currentStepData.forced_reason = reason || null;
      fresh.features[slug].steps[currentStep] = currentStepData;
      fresh.features[slug].updated_at = new Date().toISOString();
      writeLifecycle(fresh);
    });

    return {
      passed: false,
      forced: true,
      lifecycle_status: status,
      gate_verdict: verdict,
      override_allowed: true,
      blocking_reason: blockingReason,
    };
  }

  return {
    passed: false,
    forced: false,
    lifecycle_status: status,
    gate_verdict: verdict,
    override_allowed: overrideAllowed,
    blocking_reason: blockingReason,
  };
}

function main() {
  const args = process.argv.slice(2);
  const feature = args[0];
  const requiredStep = args[1];

  if (!feature || !requiredStep) {
    console.error(
      'Usage: gate-check <feature> <required-step> [--rigor lite|standard|strict] [--force] [--reason "..."]',
    );
    process.exit(1);
  }

  if (!STEPS.includes(requiredStep)) {
    console.error(`Invalid step: ${requiredStep}. Valid: ${STEPS.join(", ")}`);
    process.exit(1);
  }

  const flagArgs = args.slice(2);
  const rigor = parseFlag(flagArgs, "--rigor") || "standard";
  if (!VALID_RIGOR.includes(rigor)) {
    console.error(`Invalid rigor: ${rigor}. Valid: ${VALID_RIGOR.join(", ")}`);
    process.exit(1);
  }
  const force = flagArgs.includes("--force");
  const reason = parseFlag(flagArgs, "--reason");

  const result = gateCheck(feature, requiredStep, { rigor, force, reason });
  console.log(JSON.stringify(result));

  if (!result.passed && !result.forced) {
    process.exit(1);
  }
}

module.exports = { gateCheck, PASSING_VERDICTS, VALID_RIGOR };

if (require.main === module) {
  main();
}
