#!/usr/bin/env node
import {
  existsSync,
  readdirSync,
  readFileSync,
  statSync,
} from "node:fs";
import path from "node:path";

const workspace = process.cwd();
const agentsDir = path.join(workspace, ".agents");
const runsDir = path.join(agentsDir, "runs");
const checkpointPath = path.join(agentsDir, "checkpoint.json");
const tailLines = parseTailLines(process.argv);

main();

function main() {
  const checkpoint = readJsonIfExists(checkpointPath);
  const runs = listRuns();
  const activeRunId = checkpoint?.active_run_id || findLatestRunId(runs);

  printHeader(checkpoint, runs);

  if (runs.length === 0) {
    console.log("No runs found under .agents/runs.");
    console.log("Next: create .agents/runs/<run-id>/ with state.json and agents.json.");
    return;
  }

  for (const run of runs) {
    printRun(run, run.id === activeRunId);
  }

  const activeRun = runs.find((run) => run.id === activeRunId);
  if (activeRun) {
    printProgressTail(activeRun);
  }
}

function parseTailLines(argv) {
  const tailIndex = argv.findIndex((arg) => arg === "--tail" || arg === "-n");
  if (tailIndex === -1) return 30;
  const value = Number(argv[tailIndex + 1]);
  if (!Number.isFinite(value) || value < 0) return 30;
  return Math.floor(value);
}

function printHeader(checkpoint, runs) {
  console.log("Agent Orchestration Status");
  console.log("==========================");
  console.log(`Workspace: ${workspace}`);
  console.log(`Runs: ${runs.length}`);
  console.log(`Active run: ${checkpoint?.active_run_id || "(none)"}`);
  console.log(`Current phase: ${checkpoint?.current_phase || "(unknown)"}`);
  console.log(`Active branch: ${checkpoint?.active_branch || "(none)"}`);
  console.log(`Next action: ${checkpoint?.next_action || "(none recorded)"}`);

  const blockers = Array.isArray(checkpoint?.blockers) ? checkpoint.blockers : [];
  if (blockers.length > 0) {
    console.log("Blockers:");
    for (const blocker of blockers) {
      console.log(`- ${blocker}`);
    }
  }
  console.log("");
}

function listRuns() {
  if (!existsSync(runsDir)) return [];

  return readdirSync(runsDir)
    .map((name) => path.join(runsDir, name))
    .filter((runPath) => statSync(runPath).isDirectory())
    .map((runPath) => {
      const id = path.basename(runPath);
      return {
        id,
        path: runPath,
        state: readJsonIfExists(path.join(runPath, "state.json")),
        agents: normalizeAgents(readJsonIfExists(path.join(runPath, "agents.json"))),
        mtimeMs: statSync(runPath).mtimeMs,
      };
    })
    .sort((a, b) => a.id.localeCompare(b.id));
}

function normalizeAgents(value) {
  if (!value) return [];
  if (Array.isArray(value)) return value;
  if (Array.isArray(value.agents)) return value.agents;
  return Object.entries(value).map(([role, agent]) => ({
    role,
    ...(typeof agent === "object" && agent ? agent : { status: String(agent) }),
  }));
}

function findLatestRunId(runs) {
  if (runs.length === 0) return null;
  return runs.reduce((latest, run) => (run.mtimeMs > latest.mtimeMs ? run : latest)).id;
}

function printRun(run, isActive) {
  const state = run.state || {};
  const marker = isActive ? "*" : "-";
  console.log(`${marker} Run: ${run.id}`);
  console.log(`  Phase: ${state.current_phase || state.phase || "(unknown)"}`);
  console.log(`  Branch: ${state.current_branch || state.branch || "(none)"}`);
  console.log(`  Expected output: ${state.expected_output_artifact || state.expected_output || "(none)"}`);
  console.log(`  Retry count: ${state.retry_count ?? 0}`);
  console.log(`  Next action: ${state.next_action || "(none recorded)"}`);
  if (state.blocker) console.log(`  Blocker: ${state.blocker}`);

  if (run.agents.length === 0) {
    console.log("  Agents: none recorded");
  } else {
    console.log("  Agents:");
    for (const agent of run.agents) {
      printAgent(agent);
    }
  }
  console.log("");
}

function printAgent(agent) {
  const role = agent.role || "(unknown-role)";
  const status = agent.status || "(unknown)";
  const heartbeat = agent.heartbeat_at || "(none)";
  const lease = agent.lease_expires_at || "(none)";
  const expired = isExpired(agent.lease_expires_at);
  const thread = agent.thread_id || agent.process_id || agent.tool_call_id || "(none)";

  console.log(`    - ${role}: ${status}${expired ? " [lease expired]" : ""}`);
  console.log(`      heartbeat: ${heartbeat}`);
  console.log(`      lease: ${lease}`);
  console.log(`      id: ${thread}`);
  if (agent.last_error) {
    console.log(`      last_error: ${agent.last_error}`);
  }
}

function printProgressTail(run) {
  if (tailLines === 0) return;

  const candidateNames = [
    "progress.log",
    "implementation-log.md",
    "validation.md",
    "opus-proposal.md",
    "snarky-review.md",
  ];
  const progressPath = candidateNames
    .map((name) => path.join(run.path, name))
    .find((candidate) => existsSync(candidate) && statSync(candidate).isFile());

  console.log("Progress Tail");
  console.log("=============");

  if (!progressPath) {
    console.log(`No progress file found for run ${run.id}.`);
    console.log("Expected one of: progress.log, implementation-log.md, validation.md.");
    return;
  }

  console.log(`${path.relative(workspace, progressPath)} last ${tailLines} lines:`);
  const lines = readFileSync(progressPath, "utf8").split(/\r?\n/);
  if (lines.length > 0 && lines[lines.length - 1] === "") {
    lines.pop();
  }
  const tail = lines.slice(Math.max(0, lines.length - tailLines));
  for (const line of tail) {
    console.log(line);
  }
}

function isExpired(value) {
  if (!value) return false;
  const time = Date.parse(value);
  if (!Number.isFinite(time)) return false;
  return time < Date.now();
}

function readJsonIfExists(filePath) {
  if (!existsSync(filePath)) return null;
  try {
    return JSON.parse(readFileSync(filePath, "utf8"));
  } catch (error) {
    return {
      parse_error: error.message,
    };
  }
}
