/**
 * commands/init.ts — Initialize a directory for AI Literacy Framework.
 *
 * Creates the .ailf/ directory structure with example configuration and
 * task files. The generated files are ready-to-edit starting points —
 * not live evaluation tasks.
 *
 * TypeScript output (default) uses define* helpers from @sanity/ailf
 * for full IDE autocomplete and type checking. YAML output serializes the
 * parsed task data. JSON output is a plain serialization of the parsed data.
 *
 * Usage:
 *   ailf init                        # TypeScript output (default)
 *   ailf init --format yaml          # YAML output
 *   ailf init --format json          # JSON output
 *   ailf init --force                # overwrite existing files
 *   ailf init --path ./my-dir        # target a specific directory
 */
import { Command } from "commander";
import { existsSync, mkdirSync, writeFileSync } from "fs";
import { resolve, relative } from "path";
import { ailfConfigData, ailfConfigYaml, ailfConfigTs, taskYamlFiles, taskTsFiles, TASK_FILE_NAMES, TASK_EXAMPLES, allTaskData, workflowYaml, } from "../_vendor/ailf-core/index.js";
import { probeUserLocalAilf } from "../adapters/config-sources/ailf-resolver.js";
// ---------------------------------------------------------------------------
// Command factory
// ---------------------------------------------------------------------------
export function createInitCommand() {
    return new Command("init")
        .description("Initialize a directory for AI Literacy Framework evaluation")
        .option("-f, --format <fmt>", 'Output format for generated files: "ts" (default), "yaml", or "json"', "ts")
        .option("--force", "Overwrite existing files", false)
        .option("--path <dir>", "Target directory (default: current directory)", ".")
        .option("--mode <mode>", "Scaffold for a specific mode: literacy, mcp-server, custom (default: all modes)")
        .action(async (opts) => {
        await runInit(opts);
    });
}
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
/**
 * Write a file if it doesn't exist (or --force is set).
 * Returns true if the file was written, false if skipped.
 */
function writeIfNew(filePath, content, force) {
    if (existsSync(filePath) && !force) {
        return false;
    }
    writeFileSync(filePath, content, "utf-8");
    return true;
}
/** Relative path for display, prefixed with ./ */
function rel(from, to) {
    const r = relative(from, to);
    return r.startsWith(".") ? r : `./${r}`;
}
/** Filter task stems by mode using TASK_EXAMPLES metadata */
function taskStemsForMode(mode) {
    return TASK_EXAMPLES.filter((t) => t.mode === mode).map((t) => t.stem);
}
// ---------------------------------------------------------------------------
// Init logic
// ---------------------------------------------------------------------------
export async function runInit(opts) {
    const validFormats = new Set(["ts", "yaml", "json"]);
    if (!validFormats.has(opts.format)) {
        console.error(`  ✗ Invalid output format "${opts.format}". Valid options: ts, yaml, json`);
        process.exitCode = 1;
        return;
    }
    const format = opts.format;
    const force = opts.force;
    if (format === "yaml") {
        console.warn("  ⚠ --format yaml is deprecated. TypeScript (default) is the\n" +
            "    recommended format — it provides full IDE autocomplete via defineTask().\n" +
            "    YAML output will be removed in a future release.\n");
    }
    // Resolve target from the caller's actual working directory
    const callerCwd = process.env.AILF_CALLER_CWD ?? process.cwd();
    const targetDir = resolve(callerCwd, opts.path);
    const ailfDir = resolve(targetDir, ".ailf");
    const tasksDir = resolve(ailfDir, "tasks");
    console.log();
    console.log("  🚀 Initializing AI Literacy Framework");
    console.log();
    if (format === "ts" && !probeUserLocalAilf(targetDir)) {
        console.log("  ℹ @sanity/ailf is not installed in this project yet.");
        console.log("    For reproducibility and IDE autocomplete, install it after init:");
        console.log("      npm install -D @sanity/ailf   (or pnpm add -D, yarn add -D)");
        console.log("    The pipeline will fall back to the CLI's bundled copy until you do.");
        console.log();
    }
    // 1. Create directories
    mkdirSync(tasksDir, { recursive: true });
    console.log(`  ✓ Created ${rel(targetDir, ailfDir)}/`);
    console.log(`  ✓ Created ${rel(targetDir, tasksDir)}/`);
    const written = [];
    const skipped = [];
    // 2. Write project config
    if (format === "ts") {
        // TypeScript: ailf.config.ts with defineConfig helper
        const configPath = resolve(ailfDir, "ailf.config.ts");
        if (writeIfNew(configPath, ailfConfigTs, force)) {
            written.push(rel(targetDir, configPath));
        }
        else {
            skipped.push(rel(targetDir, configPath));
        }
    }
    else if (format === "yaml") {
        // YAML: raw string passthrough (preserves comments)
        const configPath = resolve(ailfDir, "config.yaml");
        if (writeIfNew(configPath, ailfConfigYaml, force)) {
            written.push(rel(targetDir, configPath));
        }
        else {
            skipped.push(rel(targetDir, configPath));
        }
    }
    else {
        // JSON: serialize the parsed data
        const configPath = resolve(ailfDir, "config.json");
        const content = JSON.stringify(ailfConfigData, null, 2) + "\n";
        if (writeIfNew(configPath, content, force)) {
            written.push(rel(targetDir, configPath));
        }
        else {
            skipped.push(rel(targetDir, configPath));
        }
    }
    // 3. Write example tasks to .ailf/tasks/
    const modeFilter = opts.mode;
    const isCustomMode = modeFilter === "custom";
    // Determine which task stems to write based on mode filter
    let stemsToWrite;
    if (isCustomMode) {
        // Custom mode: write one literacy example as a starting point
        stemsToWrite = taskStemsForMode("literacy").slice(0, 1);
    }
    else if (modeFilter === "literacy") {
        stemsToWrite = taskStemsForMode("literacy");
    }
    else if (modeFilter === "mcp-server") {
        stemsToWrite = taskStemsForMode("mcp-server");
    }
    else if (modeFilter === "knowledge-probe") {
        stemsToWrite = taskStemsForMode("knowledge-probe");
    }
    else if (modeFilter === "agent-harness") {
        stemsToWrite = taskStemsForMode("agent-harness");
    }
    else {
        // Default (no --mode): write all tasks
        stemsToWrite = [...TASK_FILE_NAMES];
    }
    if (format === "ts") {
        for (const stem of stemsToWrite) {
            let content = taskTsFiles[stem];
            if (!content)
                continue;
            // For MCP-only init, activate the draft task
            if (modeFilter === "mcp-server") {
                content = content.replace('status: "draft",', '// status: "active", // Activated — this task runs in evaluations');
            }
            const fileName = isCustomMode && stem === stemsToWrite[0]
                ? "example-custom.task.ts"
                : `${stem}.task.ts`;
            const taskPath = resolve(tasksDir, fileName);
            if (writeIfNew(taskPath, content, force)) {
                written.push(rel(targetDir, taskPath));
            }
            else {
                skipped.push(rel(targetDir, taskPath));
            }
        }
    }
    else if (format === "yaml") {
        for (const stem of stemsToWrite) {
            const content = taskYamlFiles[stem];
            if (!content)
                continue;
            const taskPath = resolve(tasksDir, `${stem}.yaml`);
            if (writeIfNew(taskPath, content, force)) {
                written.push(rel(targetDir, taskPath));
            }
            else {
                skipped.push(rel(targetDir, taskPath));
            }
        }
    }
    else {
        // JSON: serialize each task's parsed data individually
        const tasks = Array.isArray(allTaskData)
            ? allTaskData
            : [allTaskData];
        // Build a set of task IDs that match the selected stems
        const selectedIds = new Set(stemsToWrite.flatMap((s) => TASK_EXAMPLES.filter((t) => t.stem === s).map((t) => t.stem)));
        for (const task of tasks) {
            const taskId = task.id;
            if (!selectedIds.has(taskId))
                continue;
            const taskPath = resolve(tasksDir, `${taskId}.json`);
            const content = JSON.stringify([task], null, 2) + "\n";
            if (writeIfNew(taskPath, content, force)) {
                written.push(rel(targetDir, taskPath));
            }
            else {
                skipped.push(rel(targetDir, taskPath));
            }
        }
    }
    // 3b. Write custom preset scaffold (--mode custom only)
    if (isCustomMode && format === "ts") {
        const presetPath = resolve(ailfDir, "preset.ts");
        if (writeIfNew(presetPath, CUSTOM_PRESET_TS, force)) {
            written.push(rel(targetDir, presetPath));
        }
        else {
            skipped.push(rel(targetDir, presetPath));
        }
    }
    // 4. Write .gitignore in .ailf/ (keep results out of version control)
    const gitignorePath = resolve(ailfDir, ".gitignore");
    const gitignoreContent = `# AILF generated files\nresults/\ncontexts/\n`;
    if (writeIfNew(gitignorePath, gitignoreContent, force)) {
        written.push(rel(targetDir, gitignorePath));
    }
    else {
        skipped.push(rel(targetDir, gitignorePath));
    }
    // 5. Write GitHub Actions workflow
    const workflowDir = resolve(targetDir, ".github", "workflows");
    const workflowPath = resolve(workflowDir, "ailf-eval.yml");
    mkdirSync(workflowDir, { recursive: true });
    if (writeIfNew(workflowPath, workflowYaml, force)) {
        written.push(rel(targetDir, workflowPath));
    }
    else {
        skipped.push(rel(targetDir, workflowPath));
    }
    // 6. Summary
    console.log();
    if (written.length > 0) {
        for (const f of written) {
            console.log(`  ✓ Created ${f}`);
        }
    }
    if (skipped.length > 0) {
        console.log();
        for (const f of skipped) {
            console.log(`  ⊘ Skipped ${f} (already exists, use --force to overwrite)`);
        }
    }
    const taskExt = format === "ts" ? ".task.ts" : format === "yaml" ? ".yaml" : ".json";
    console.log();
    console.log("  Next steps:");
    console.log();
    console.log(`  1. Edit the example tasks in ${rel(targetDir, tasksDir)}/ — update`);
    console.log("     slugs and prompts for your documentation");
    console.log(`  2. Validate locally: npx @sanity/ailf@latest validate-tasks .ailf/tasks/`);
    console.log();
    console.log('     Note: tasks with status: "draft" are skipped on normal runs.');
    console.log("     To run one anyway, target it explicitly with --task <id>, e.g.:");
    console.log("       npx @sanity/ailf@latest pipeline --task example-agent-add-schema");
    console.log();
    console.log("  3. Add a GitHub Actions secret");
    console.log("     (Settings → Secrets and variables → Actions):");
    console.log("     • AILF_API_KEY — your API key");
    console.log("  4. Push — the workflow at .github/workflows/ailf-eval.yml runs");
    console.log("     automatically on PRs");
    if (format === "ts") {
        console.log();
        console.log(`  💡 TypeScript tasks (${taskExt}) give you full IDE autocomplete`);
        console.log("     via defineTask() from @sanity/ailf.");
    }
    console.log();
    console.log("  🔑 Retrieve the API key from 1Password (Sanity employees):");
    console.log();
    console.log("     # Shared dev API key (for local testing and CI)");
    console.log('     op read "op://Shared/AI Literacy Framework - Shared API Tokens/AILF_API_KEY_DEV"');
    console.log();
    console.log("     Not a Sanity employee? Request an API key from the AILF team.");
    console.log();
    console.log("  💡 Test a remote run (executes against the AILF API) before pushing:");
    console.log("     AILF_API_KEY=... npx @sanity/ailf@latest pipeline --remote --debug");
    console.log();
    console.log("  💡 Or test a remote run against your repo tasks:");
    console.log("     # First, set `taskSource: { type: repo }` in .ailf/config.yaml");
    console.log("     AILF_API_KEY=... npx @sanity/ailf@latest run --remote --debug");
    console.log();
    console.log("  💡 Or run locally against your repo tasks:");
    console.log("     AILF_API_KEY=... npx @sanity/ailf@latest run --mode=literacy --variant=full --debug --explain -y");
    console.log();
}
// ---------------------------------------------------------------------------
// Custom preset scaffold template
// ---------------------------------------------------------------------------
const CUSTOM_PRESET_TS = `/**
 * Custom preset — your domain-specific evaluation configuration.
 *
 * This preset targets the "literacy" mode base and inherits its evaluation
 * methodology (rubrics, scoring profiles, prompt templates). You only need
 * to provide domain-specific configuration: where your docs live, what
 * features to track, and how to fetch documentation.
 *
 * To use a different mode (e.g., "mcp-server"), change the mode field.
 * Available built-in modes: literacy, mcp-server, knowledge-probe, agent-harness.
 *
 * @see https://github.com/sanity-labs/ai-literacy-framework/blob/main/docs/presets.md
 */

import { definePreset } from "@sanity/ailf"

export default definePreset({
  name: "my-docs-evaluation",
  manifest: {
    name: "my-docs-evaluation",
    version: "1.0.0",
    description: "Documentation literacy evaluation for my project.",
    pluginApiVersion: 1,
  },

  // Target the literacy mode base — inherits rubrics, scoring, prompts.
  // Change to "mcp-server" to evaluate MCP tool usage instead.
  mode: "literacy",

  // Source definitions — where your documentation lives.
  sourceDefs: [
    {
      name: "production",
      baseUrl: "https://docs.example.com",
      // projectId: "your-sanity-project-id",
      // dataset: "production",
    },
  ],

  // Feature registry — what product features you're tracking coverage for.
  featureDefs: {
    features: [
      {
        id: "getting-started",
        name: "Getting Started Guide",
        sections: ["guides"],
        status: "covered",
        area: "guides",
        priority: "critical",
      },
      {
        id: "api-reference",
        name: "API Reference",
        sections: ["reference"],
        status: "uncovered",
        priority: "high",
      },
    ],
  },

  // Optional: override mode base rubrics, scoring, or prompts here.
  // rubricTemplates: [{ ... }],
  // scoringProfiles: { ... },
  // promptTemplates: { ... },
})
`;
