#!/usr/bin/env node

import { spawn, spawnSync } from "node:child_process";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { readFileSync } from "node:fs";

const __dirname = dirname(fileURLToPath(import.meta.url));
const root = resolve(__dirname, "..");
const script = resolve(root, "lib", "kairo_cli.py");
const pkg = JSON.parse(readFileSync(resolve(root, "package.json"), "utf8"));
const args = process.argv.slice(2);

if (args.length === 1 && (args[0] === "--version" || args[0] === "-v")) {
  console.log(pkg.version);
  process.exit(0);
}

if (args.length === 1 && (args[0] === "--help" || args[0] === "-h")) {
  console.log(`Kairo ${pkg.version}

Usage:
  kairolite                 Start the agent (auto-starts the local model server)
  kairolite -p "<prompt>"   Run one prompt non-interactively, then exit
  kairolite model           Show model status / download the model on demand
  kairolite serve [options] Run only the model server in the foreground
  kairolite stop            Stop any running model server and free its memory
  kairolite gpu             Scan for an NVIDIA GPU and link the faster GPU build
  kairolite doctor          Show setup status and local server detection
  kairolite [options]

Commands:
  (no command)        Auto-start the bundled model server, then open the agent
  model               Download the bundled Qwen model, or show its status
  setup               Check local requirements for the bundled Qwen model target
  serve               Start the tinyq4 server with the default Qwen model
  stop                Stop any running tinyq4 server and free its memory
  gpu                 Detect an NVIDIA GPU and point to the faster GPU build
  doctor              Show setup status and local server detection

Options:
  -p, --print <text>   Run a single prompt and exit ("-" reads it from stdin)
  --url <url>          OpenAI-compatible base URL, for example http://127.0.0.1:18081
  --port <port>        Local OpenAI-compatible server port
  --workspace <path>   Workspace directory, defaults to the current directory
  --yolo               Run write/bash tools without confirmation
  --max-steps <n>      Max tool-loop steps per prompt, defaults to 25
  --version            Print package version
  --help               Show this help

In-chat commands:
  /yolo /tools /model /gpu /save [file] /cwd /stats /clear /help /exit

Environment:
  KAIRO_BASE_URL       Same as --url
  KAIRO_PORT           Same as --port
  KAIRO_MAX_STEPS      Same as --max-steps
`);
  process.exit(0);
}

const candidates = process.platform === "win32"
  ? [
      ["py", ["-3"]],
      ["python", []],
      ["python3", []]
    ]
  : [
      ["python3", []],
      ["python", []]
    ];

const selected = candidates.find(([cmd, baseArgs]) => {
  const result = spawnSync(cmd, [...baseArgs, "--version"], { stdio: "ignore" });
  return result.status === 0;
});

if (!selected) {
  // During `npm install` (postinstall) a missing Python must NOT break the
  // install. Warn and exit cleanly; the model downloads on first run instead.
  if (args[0] === "postinstall") {
    console.warn(
      "kairolite: Python 3 was not found, so the model was not pre-downloaded.\n" +
      "            Install python3, then run `kairolite model` to fetch it."
    );
    process.exit(0);
  }
  console.error("kairolite: Python 3 is required. Install python3 and try again.");
  process.exit(1);
}

const [python, baseArgs] = selected;
const child = spawn(python, [...baseArgs, script, ...args], {
  stdio: "inherit",
  env: process.env
});

child.on("exit", (code, signal) => {
  if (signal) {
    process.kill(process.pid, signal);
    return;
  }
  process.exit(code ?? 0);
});

child.on("error", (error) => {
  console.error(`kairolite: failed to launch Python: ${error.message}`);
  process.exit(1);
});
