/**
 * cmd-verify.js — `qa-stlc verify`
 *
 * Quick sanity checks:
 *   1. Are the four Python MCP agents on PATH (or in .venv)?
 *   2. Is Playwright MCP reachable on the expected port?
 *   3. Is MSAL auth cache present?
 */
"use strict";

const path   = require("path");
const fs     = require("fs");
const http   = require("http");
const https  = require("https");
const { spawnSync } = require("child_process");
const os     = require("os");

const C = {
  reset: "\x1b[0m", bold: "\x1b[1m",
  green: "\x1b[32m", yellow: "\x1b[33m", red: "\x1b[31m", dim: "\x1b[2m",
};
const ok   = (m) => console.log(`  ${C.green}✓${C.reset}  ${m}`);
const fail = (m) => console.log(`  ${C.red}✗${C.reset}  ${m}`);
const warn = (m) => console.log(`  ${C.yellow}⚠${C.reset}  ${m}`);
const head = (m) => console.log(`\n${C.bold}${m}${C.reset}`);

const PREF_FILE_V = require("path").join(os.homedir(), ".qa-stlc", "integration");

function readIntegrationPrefV() {
  try {
    if (fs.existsSync(PREF_FILE_V))
      return fs.readFileSync(PREF_FILE_V, "utf8").trim();
  } catch (_) {}
  return "ado";
}

const CWD    = process.cwd();
const IS_WIN = process.platform === "win32";
const EXT    = IS_WIN ? ".exe" : "";

const AGENT_NAMES = [
  "qa-test-case-manager",
  "qa-gherkin-generator",
  "qa-playwright-generator",
  "qa-helix-writer",
  "qa-migration",
  "qa-jira-manager",
];

function findBinary(name) {
  // .venv first
  const venvBin = IS_WIN
    ? path.join(CWD, ".venv", "Scripts", name + EXT)
    : path.join(CWD, ".venv", "bin", name);
  if (fs.existsSync(venvBin)) return venvBin;
  // system PATH
  const w = spawnSync(IS_WIN ? "where" : "which", [name], { encoding: "utf8" });
  if (w.status === 0 && w.stdout.trim()) return w.stdout.trim().split("\n")[0].trim();
  return null;
}

function checkPort(port) {
  return new Promise((resolve) => {
    const req = http.get(`http://localhost:${port}/`, (res) => {
      res.destroy();
      resolve(true);
    });
    req.setTimeout(2000, () => { req.destroy(); resolve(false); });
    req.on("error", () => resolve(false));
  });
}

module.exports = async function verify(opts) {
  const playwrightPort = opts.playwrightPort || "8931";
  let allOk = true;

  // ── 1. Python agents ──────────────────────────────────────────────────────
  const integration = (opts.integration || readIntegrationPrefV() || "ado").toLowerCase();
  const needsAdo  = integration === "ado"  || integration === "both";
  const needsJira = integration === "jira" || integration === "both";
  // Shared agents (Gherkin, Playwright, Helix) are required by both ADO and Jira pipelines.
  const activeNames = [
    ...((needsAdo || needsJira) ? AGENT_NAMES : []),
    ...(needsJira ? ["qa-jira-manager"] : []),
  ].filter((v, i, a) => a.indexOf(v) === i); // deduplicate for 'both' case

  head(`Python MCP Agents  (integration: ${C.bold}${integration}${C.reset})`);
  for (const name of activeNames) {
    const bin = findBinary(name);
    if (bin) {
      ok(`${name}  ${C.dim}${bin}${C.reset}`);
    } else {
      fail(`${name}  — not found`);
      allOk = false;
    }
  }
  if (!allOk) {
    console.log(`\n  ${C.yellow}Fix: pip install qa-gentic-stlc-agents${C.reset}`);
  }

  // ── 2. Playwright MCP ─────────────────────────────────────────────────────
  head("Playwright MCP");
  const pwReachable = await checkPort(playwrightPort);
  if (pwReachable) {
    ok(`Reachable on port ${playwrightPort}`);
  } else {
    warn(`Not reachable on port ${playwrightPort}  ${C.dim}(start it with: npx @playwright/mcp@latest --port ${playwrightPort})${C.reset}`);
    // Don't fail — it's optional until generation time
  }

  // ── 3. MSAL token cache ───────────────────────────────────────────────────
  head("Azure DevOps Auth (MSAL)");
  const msalCache = path.join(os.homedir(), ".msal-cache", "msal-cache.json");
  if (fs.existsSync(msalCache)) {
    const stat = fs.statSync(msalCache);
    ok(`Token cache found  ${C.dim}${msalCache}  (${Math.round(stat.size / 1024)} KB)${C.reset}`);
  } else {
    warn(`No MSAL cache at ${msalCache}`);
    warn(`A browser will open the first time an agent calls Azure DevOps.`);
    warn(`Set AZURE_CLIENT_ID + AZURE_CLIENT_SECRET + AZURE_TENANT_ID for CI/CD.`);
  }

  // ── 3b. Jira auth cache ──────────────────────────────────────────────────────
  head("Jira Auth (OAuth 2.0)");
  const jiraCache = path.join(os.homedir(), ".jira-cache", "jira-token.json");
  if (fs.existsSync(jiraCache)) {
    const stat = fs.statSync(jiraCache);
    ok(`Token cache found  ${C.dim}${jiraCache}  (${Math.round(stat.size / 1024)} KB)${C.reset}`);
  } else {
    warn(`No Jira token cache at ${jiraCache}`);
    warn(`A browser will open the first time qa-jira-manager is called.`);
    warn(`Set JIRA_CLIENT_ID + JIRA_CLIENT_SECRET + JIRA_CLOUD_ID in .env`);
  }

  // ── 4. MCP config files ───────────────────────────────────────────────────
  head("MCP Config");
  const mcpJson   = path.join(CWD, ".mcp.json");
  const vscodeMcp = path.join(CWD, ".vscode", "mcp.json");
  if (fs.existsSync(mcpJson))   ok(`.mcp.json present`);
  else                          warn(`.mcp.json missing  — run: qa-stlc mcp-config`);
  if (fs.existsSync(vscodeMcp)) ok(`.vscode/mcp.json present`);
  else                          warn(`.vscode/mcp.json missing  — run: qa-stlc mcp-config --vscode`);

  // ── 5. Skills ─────────────────────────────────────────────────────────────
  head("Skills");
  const claudeSkills = path.join(CWD, ".claude", "skills");
  const copilotSkills = path.join(CWD, ".github", "copilot-instructions");
  if (fs.existsSync(claudeSkills)) {
    const files = fs.readdirSync(claudeSkills).filter((f) => f.endsWith(".md"));
    ok(`Claude Code skills (${files.length} files)  ${C.dim}${claudeSkills}${C.reset}`);
  } else {
    warn(`No Claude Code skills  — run: qa-stlc skills`);
  }
  if (fs.existsSync(copilotSkills)) {
    const files = fs.readdirSync(copilotSkills).filter((f) => f.endsWith(".md"));
    ok(`Copilot instructions (${files.length} files)  ${C.dim}${copilotSkills}${C.reset}`);
  } else {
    warn(`No Copilot instructions  — run: qa-stlc skills --target vscode`);
  }

  console.log();
};