/**
 * Internal subprocess entry point for store-backed code chunking.
 * Spawned via chunkFromStoreIsolated — not a public API.
 */
import { join } from 'node:path';
import { tmpdir } from 'node:os';
import { rm } from 'node:fs/promises';
import { chunkFromIndex, chunkFromIndexCooperative, chunkFromIndexStreaming } from './chunk.js';
import { CodeIndexBudgetExceededError } from './build.js';
import { writeNdjsonFile } from './index-io.js';
import { openCodeIndexStore } from './store.js';
import { createTokenizer } from '../tokens.js';
import { abortIfNeeded, createYielder, isCooperative } from '../utils.js';
function send(msg) {
    process.send?.(msg);
}
async function resolveChunkOptions(options) {
    if (!options)
        return undefined;
    const { tokenizer, ...chunkOptions } = options;
    if (!tokenizer)
        return chunkOptions;
    const resolved = await createTokenizer(tokenizer);
    return {
        ...chunkOptions,
        countTokens: text => resolved.count(text),
    };
}
let abortController;
process.on('message', async (msg) => {
    if (msg.type === 'abort') {
        abortController?.abort();
        return;
    }
    if (msg.type !== 'start')
        return;
    const store = openCodeIndexStore(msg.options.store);
    let resultPath;
    try {
        abortController = new AbortController();
        const signal = abortController.signal;
        const cooperative = msg.options.cooperative;
        const yielder = isCooperative(cooperative) ? createYielder(cooperative, signal) : undefined;
        const chunkOptions = await resolveChunkOptions(msg.options.chunk);
        const session = await store.getSession({
            strategy: msg.options.strategy ?? 'ensure-fresh',
            signal,
            cooperative,
            onProgress: (event) => {
                send({ type: 'progress', event });
            },
        });
        abortIfNeeded(signal);
        const index = session.getIndex();
        send({
            type: 'progress',
            event: {
                phase: 'chunk',
                total: index.files.length,
                completed: 0,
                detail: 'Chunking code files',
                scope: 'code',
            },
        });
        const chunks = index.contentMode === 'full'
            ? yielder
                ? await chunkFromIndexCooperative(index, chunkOptions, yielder)
                : chunkFromIndex(index, chunkOptions)
            : await chunkFromIndexStreaming(index, chunkOptions, { signal, yielder });
        abortIfNeeded(signal);
        send({
            type: 'progress',
            event: {
                phase: 'chunk',
                total: chunks.length,
                completed: chunks.length,
                detail: 'Code chunking complete',
                scope: 'code',
            },
        });
        resultPath = join(tmpdir(), `occ-code-chunks-${process.pid}-${Date.now()}.ndjson`);
        await writeNdjsonFile(resultPath, chunks, signal);
        send({ type: 'complete', resultPath });
    }
    catch (err) {
        const error = err instanceof Error ? err : new Error(String(err));
        // Remove any partially written artifact so an aborted/failed chunk run leaves
        // nothing behind for the parent to clean.
        if (resultPath) {
            await rm(resultPath, { force: true }).catch(() => undefined);
        }
        if (error.name === 'AbortError') {
            send({ type: 'aborted' });
        }
        else {
            const code = error.code;
            send({
                type: 'error',
                message: error.message,
                name: error.name,
                code: typeof code === 'string' ? code : undefined,
                budget: error instanceof CodeIndexBudgetExceededError ? error.budget : undefined,
            });
        }
    }
    finally {
        store.dispose();
    }
    process.disconnect?.();
});
//# sourceMappingURL=isolated-chunk-runner.js.map