import path from "node:path";

import type { AgentMeta, AgentParseResult, AgentSpec } from "./types.js";

function parseCodexJson(raw: string): AgentParseResult {
  const lines = raw.split(/\n+/).filter((l) => l.trim().startsWith("{"));
  let text: string | undefined;
  let meta: AgentMeta | undefined;

  for (const line of lines) {
    try {
      const ev = JSON.parse(line) as {
        type?: string;
        item?: { type?: string; text?: string };
        usage?: unknown;
      };
      // Codex streams multiple events; capture the last agent_message text and
      // the final turn usage for cost/telemetry.
      if (
        ev.type === "item.completed" &&
        ev.item?.type === "agent_message" &&
        typeof ev.item.text === "string"
      ) {
        text = ev.item.text;
      }
      if (
        ev.type === "turn.completed" &&
        ev.usage &&
        typeof ev.usage === "object"
      ) {
        const u = ev.usage as {
          input_tokens?: number;
          cached_input_tokens?: number;
          output_tokens?: number;
        };
        meta = {
          usage: {
            input: u.input_tokens,
            output: u.output_tokens,
            cacheRead: u.cached_input_tokens,
            total:
              (u.input_tokens ?? 0) +
              (u.output_tokens ?? 0) +
              (u.cached_input_tokens ?? 0),
          },
        };
      }
    } catch {
      // ignore
    }
  }

  return { text: text?.trim(), meta };
}

export const codexSpec: AgentSpec = {
  kind: "codex",
  isInvocation: (argv) => argv.length > 0 && path.basename(argv[0]) === "codex",
  buildArgs: (ctx) => {
    const argv = [...ctx.argv];
    const hasExec = argv.length > 0 && argv[1] === "exec";
    if (!hasExec) {
      argv.splice(1, 0, "exec");
    }
    // Ensure JSON output
    if (!argv.includes("--json")) {
      argv.splice(argv.length - 1, 0, "--json");
    }
    // Safety defaults
    if (!argv.includes("--skip-git-repo-check")) {
      argv.splice(argv.length - 1, 0, "--skip-git-repo-check");
    }
    if (!argv.some((p) => p === "--sandbox" || p.startsWith("--sandbox="))) {
      argv.splice(argv.length - 1, 0, "--sandbox", "read-only");
    }
    return argv;
  },
  parseOutput: parseCodexJson,
};
