#!/usr/bin/env node

/**
 * ailf — CLI launcher for the AI Literacy Framework.
 *
 * Runs in two modes:
 * 1. **Development** (monorepo) — delegates to TypeScript source via tsx.
 *    Detected by the presence of src/cli.ts.
 * 2. **Production** (npm install) — imports the compiled dist/cli.js directly.
 *    This is the path when installed via `npx @sanity/ailf-eval` or
 *    `pnpm add @sanity/ailf-eval`.
 */

import { existsSync } from "fs"
import { execFileSync } from "child_process"
import { dirname, resolve } from "path"
import { fileURLToPath } from "url"

const __dirname = dirname(fileURLToPath(import.meta.url))
const ROOT = resolve(__dirname, "..")
const tsSrc = resolve(ROOT, "src", "cli.ts")
const jsDist = resolve(ROOT, "dist", "cli.js")

// Forward all arguments after the script name
const args = process.argv.slice(2)

// Preserve the caller's working directory so commands like `ailf init`
// operate on the user's cwd, not the eval package root.
const callerCwd = process.cwd()

// Test harnesses (and any caller that knows the dist is fresh) can opt out
// of the tsx dev path with AILF_PREFER_DIST=1. This avoids the npx + tsx
// cold-start cost (~1–2s per invocation) on every `spawnCli(...)` call.
const preferDist = process.env.AILF_PREFER_DIST === "1" && existsSync(jsDist)

// ---------------------------------------------------------------------------
// Mode 1: Development — tsx + TypeScript source (no build step needed)
// ---------------------------------------------------------------------------
if (existsSync(tsSrc) && !preferDist) {
  try {
    // Enable the `ailf-source` export condition so @sanity/ailf-shared and
    // @sanity/ailf-core resolve to their `src/index.ts` entrypoints rather
    // than whatever happens to be in their `dist/` directories. Without
    // this, running `ailf …` against a freshly pulled monorepo (or any
    // workspace with a stale dist) fails at import time whenever the
    // source introduces a new export that the dist hasn't caught up with.
    const existingNodeOptions = process.env.NODE_OPTIONS ?? ""
    const conditionFlag = "--conditions=ailf-source"
    const nodeOptions = existingNodeOptions.includes(conditionFlag)
      ? existingNodeOptions
      : `${existingNodeOptions} ${conditionFlag}`.trim()
    execFileSync("npx", ["tsx", tsSrc, ...args], {
      cwd: ROOT,
      env: {
        ...process.env,
        AILF_CALLER_CWD: callerCwd,
        NODE_OPTIONS: nodeOptions,
      },
      stdio: "inherit",
    })
    process.exit(0)
  } catch (err) {
    // execFileSync throws on non-zero exit codes — propagate them
    const code =
      err !== null && typeof err === "object" && "status" in err
        ? err.status
        : 1
    process.exit(code)
  }
}

// ---------------------------------------------------------------------------
// Mode 2: Production — compiled JS (npm install / npx)
// ---------------------------------------------------------------------------
if (existsSync(jsDist)) {
  // Set AILF_CALLER_CWD so cli.ts resolves paths relative to the caller
  process.env.AILF_CALLER_CWD = callerCwd
  await import(jsDist)
} else {
  console.error(
    "ailf: Cannot find CLI entry point. Run 'pnpm build' or ensure tsx is available."
  )
  process.exit(1)
}
