/**
 * fetch-docs command — pull documentation from Sanity CMS.
 *
 * Uses the composition root to wire adapters, then delegates to
 * ctx.docFetcher (SanityDocFetcher) — the same code path as the pipeline.
 */
import { mkdirSync, writeFileSync } from "fs";
import { dirname, join, resolve } from "path";
import { fileURLToPath } from "url";
import { Command } from "commander";
import { createAppContext } from "../composition-root.js";
import { loadSource } from "../sources.js";
import { configToSourceOverrides } from "../orchestration/config-to-source-overrides.js";
import { addOutputDirOption, addSanitySourceOptions } from "./shared/options.js";
import { resolveOutputDir } from "./shared/resolve-output-dir.js";
const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT = resolve(__dirname, "..", "..");
export function createFetchDocsCommand() {
    const cmd = new Command("fetch-docs")
        .description("Fetch documentation contexts from Sanity CMS")
        .option("-s, --source <name>", "Documentation source name (from sources.yaml)")
        .option("--include-feature-areas", "Generate feature-area context files", false)
        .option("--include-corpus", "Generate full corpus context file", false)
        .action(async (opts) => {
        try {
            await executeFetchDocs(opts);
        }
        catch (err) {
            process.exitCode = 1;
            if (err instanceof Error)
                console.error(err.message);
        }
    });
    addSanitySourceOptions(cmd);
    addOutputDirOption(cmd);
    return cmd;
}
// ---------------------------------------------------------------------------
// Implementation
// ---------------------------------------------------------------------------
async function executeFetchDocs(opts) {
    console.log("=== ai-literacy-framework — Documentation Fetcher ===\n");
    // Build a minimal ResolvedConfig for the composition root
    const ctx = createAppContext({
        rootDir: ROOT,
        outputDir: resolveOutputDir(opts.outputDir),
        mode: "literacy",
        noAutoScope: false,
        skipFetch: false,
        skipEval: true,
        compareEnabled: false,
        gapAnalysisEnabled: false,
        publishEnabled: false,
        noCache: true,
        noRemoteCache: true,
        searchMode: "open",
        source: opts.source,
        remote: false,
        apiUrl: "https://ailf-api.sanity.build",
    });
    // Resolve source
    const overrides = configToSourceOverrides(ctx.config);
    const resolvedSource = loadSource(ctx.config.source, overrides);
    // Log source info
    console.log(`  Source: ${resolvedSource.name}`);
    console.log(`  Base URL: ${resolvedSource.baseUrl}`);
    if (resolvedSource.dataset)
        console.log(`  Dataset: ${resolvedSource.dataset}`);
    if (resolvedSource.perspective)
        console.log(`  Perspective: ${resolvedSource.perspective}`);
    if (resolvedSource.documentIds && resolvedSource.documentIds.length > 0) {
        console.log(`  Documents: ${resolvedSource.documentIds.length} document ID(s)`);
    }
    if (resolvedSource.urls.length > 0) {
        console.log(`  URLs:      ${resolvedSource.urls.length} direct URL(s)`);
    }
    console.log();
    // The composition root wires SanityDocFetcher into ctx.docFetcher.
    // We cast to access the non-port methods (feature areas, corpus).
    const fetcher = ctx.docFetcher;
    // Feature-area contexts (opt-in)
    if (opts.includeFeatureAreas) {
        await fetcher.fetchFeatureAreaContexts(resolvedSource);
    }
    // Canonical contexts — same code path as the pipeline
    const tasks = await ctx.taskSource.loadTasks();
    // Bridge: narrow to literacy tasks with docs (only literacy tasks have context.docs)
    const tasksWithDocs = tasks.filter((t) => t.mode === "literacy" && (t.context?.docs?.length ?? 0) > 0);
    if (tasksWithDocs.length > 0) {
        console.log("\nGenerating canonical (gold-retrieval) contexts...\n");
        const result = await fetcher.fetch(tasksWithDocs, resolvedSource);
        // Write metadata files
        if (result.metadata) {
            writeMetadataFiles(ROOT, result.metadata);
        }
        console.log(`\n  Canonical contexts: ${result.contexts.length} tasks`);
        for (const docCtx of result.contexts) {
            console.log(`    ${docCtx.taskId}: ${docCtx.slugs.length} doc(s), ~${docCtx.tokenCount ?? 0} tokens`);
        }
    }
    // Full corpus (opt-in)
    if (opts.includeCorpus) {
        await fetcher.fetchFullCorpus(resolvedSource);
    }
    console.log("\nDone!");
}
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
function writeMetadataFiles(rootDir, metadata) {
    const contextsDir = join(rootDir, "contexts");
    mkdirSync(contextsDir, { recursive: true });
    if (metadata.manifest) {
        const path = join(contextsDir, "document-manifest.json");
        writeFileSync(path, JSON.stringify(metadata.manifest, null, 2));
        console.log(`  📋 Document manifest: ${metadata.manifest.length} docs → contexts/document-manifest.json`);
    }
    if (metadata.releaseImpact) {
        const path = join(contextsDir, "release-impact.json");
        writeFileSync(path, JSON.stringify(metadata.releaseImpact, null, 2));
        console.log("  📄 Release impact written to contexts/release-impact.json");
    }
    if (metadata.documentOverlay) {
        const path = join(contextsDir, "document-overlay.json");
        writeFileSync(path, JSON.stringify(metadata.documentOverlay, null, 2));
        console.log("  📄 Document overlay written to contexts/document-overlay.json");
    }
    if (metadata.urlFetch) {
        const path = join(contextsDir, "url-fetch.json");
        writeFileSync(path, JSON.stringify(metadata.urlFetch, null, 2));
        console.log("  📄 URL fetch metadata written to contexts/url-fetch.json");
    }
}
