"use strict";
// src/cli/IndexCommand.ts
// v1.13.0 — `openlife index {build,update,status,query,purge}`.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.registerIndexCommands = registerIndexCommands;
function errMsg(e) {
    return e instanceof Error ? e.message : String(e);
}
async function buildOrUpdate(rebuild, opts) {
    const { EmbeddingRegistry } = await Promise.resolve().then(() => __importStar(require('../orchestrator/rag/EmbeddingRegistry')));
    const { VectorStoreRegistry } = await Promise.resolve().then(() => __importStar(require('../orchestrator/rag/VectorStoreRegistry')));
    const { Indexer } = await Promise.resolve().then(() => __importStar(require('../orchestrator/rag/Indexer')));
    const embed = EmbeddingRegistry.create();
    const available = await embed.isAvailable();
    if (!available) {
        console.error(`[INDEX] embedding provider "${embed.name()}" not available (model=${embed.model()}).`);
        console.error(`  → If Ollama: start the daemon (\`ollama serve\`) and pull the model: \`ollama pull ${embed.model()}\`.`);
        console.error(`  → Or switch provider: OPENLIFE_EMBEDDING_PROVIDER=openai (needs OPENAI_API_KEY).`);
        process.exitCode = 1;
        return;
    }
    const store = VectorStoreRegistry.create(embed.dim());
    const root = opts.root || process.cwd();
    console.log(`[INDEX] ${rebuild ? 'rebuild' : 'update'} from ${root}`);
    console.log(`[INDEX] embed=${embed.name()}/${embed.model()} dim=${embed.dim()}`);
    const indexer = new Indexer();
    let last = '';
    const report = await indexer.build({
        root, store, embed, rebuild,
        onProgress: (file, done, total) => {
            const pct = Math.floor((done / Math.max(1, total)) * 100);
            const next = `[INDEX] ${done}/${total} (${pct}%) ${file}`;
            if (next !== last && (done % 25 === 0 || done === total)) {
                console.log(next);
                last = next;
            }
        },
    });
    await store.close();
    console.log(`[INDEX] done: scanned=${report.scannedFiles} indexed=${report.indexedFiles} skipped=${report.skippedFiles} chunks+=${report.upsertedChunks}`);
}
async function statusCmd() {
    const { EmbeddingRegistry } = await Promise.resolve().then(() => __importStar(require('../orchestrator/rag/EmbeddingRegistry')));
    const { VectorStoreRegistry } = await Promise.resolve().then(() => __importStar(require('../orchestrator/rag/VectorStoreRegistry')));
    const { defaultIndexDir } = await Promise.resolve().then(() => __importStar(require('../orchestrator/rag/SqliteVectorStore')));
    const embed = EmbeddingRegistry.create();
    const ok = await embed.isAvailable();
    console.log(`embedding: ${embed.name()}/${embed.model()} dim=${embed.dim()} available=${ok}`);
    console.log(`vector store: ${VectorStoreRegistry.selectName()}`);
    console.log(`index dir: ${defaultIndexDir()}`);
    try {
        const store = VectorStoreRegistry.create(embed.dim());
        const n = await store.size();
        console.log(`indexed chunks: ${n}`);
        await store.close();
    }
    catch (err) {
        console.log(`indexed chunks: <error: ${errMsg(err)}>`);
    }
}
async function queryCmd(q, opts) {
    const { EmbeddingRegistry } = await Promise.resolve().then(() => __importStar(require('../orchestrator/rag/EmbeddingRegistry')));
    const { VectorStoreRegistry } = await Promise.resolve().then(() => __importStar(require('../orchestrator/rag/VectorStoreRegistry')));
    const { Retriever } = await Promise.resolve().then(() => __importStar(require('../orchestrator/rag/Retriever')));
    const embed = EmbeddingRegistry.create();
    if (!(await embed.isAvailable())) {
        console.error(`[INDEX] embedding provider "${embed.name()}" not available.`);
        process.exitCode = 1;
        return;
    }
    const store = VectorStoreRegistry.create(embed.dim());
    const ret = new Retriever(embed, store);
    const hits = await ret.retrieve(q, {
        topK: opts.top ? Number(opts.top) : 8,
        file: opts.file,
        language: opts.language,
    });
    await store.close();
    for (const h of hits) {
        console.log(`\n[${h.score.toFixed(3)}] ${h.ref}`);
        const preview = h.content.split('\n').slice(0, 8).join('\n');
        console.log(preview);
    }
    if (hits.length === 0)
        console.log('(no hits — try `openlife index build` first)');
}
async function purgeCmd(opts) {
    const { EmbeddingRegistry } = await Promise.resolve().then(() => __importStar(require('../orchestrator/rag/EmbeddingRegistry')));
    const { VectorStoreRegistry } = await Promise.resolve().then(() => __importStar(require('../orchestrator/rag/VectorStoreRegistry')));
    const embed = EmbeddingRegistry.create();
    const store = VectorStoreRegistry.create(embed.dim());
    if (opts.file) {
        await store.deleteByFile(opts.file);
        console.log(`[INDEX] purged chunks for ${opts.file}`);
    }
    else {
        console.error('[INDEX] purge needs --file <path> (full DB drop is a manual `rm`)');
        process.exitCode = 1;
    }
    await store.close();
}
function registerIndexCommands(program) {
    const idx = program
        .command('index')
        .description('v1.13.0 — Codebase RAG index (build / query / status)');
    idx.command('build')
        .description('Embed and index the codebase from scratch')
        .option('--root <path>', 'Project root to index (default: cwd)')
        .action((opts) => { void buildOrUpdate(true, opts); });
    idx.command('update')
        .description('Incremental re-index — only files whose mtime changed')
        .option('--root <path>', 'Project root to index (default: cwd)')
        .action((opts) => { void buildOrUpdate(false, opts); });
    idx.command('status')
        .description('Inspect index state, provider availability, chunk count')
        .action(() => { void statusCmd(); });
    idx.command('query <q...>')
        .description('Semantic search of the codebase index')
        .option('--top <n>', 'Top-K hits (default 8)')
        .option('--file <path>', 'Restrict to one source file')
        .option('--language <lang>', 'Restrict by language tag (ts/js/py/...)')
        .action((qParts, opts) => {
        void queryCmd(qParts.join(' '), opts);
    });
    idx.command('purge')
        .description('Remove chunks from the index')
        .option('--file <path>', 'Purge a single file')
        .action((opts) => { void purgeCmd(opts); });
}
