import path from 'node:path';
import { Option } from 'commander';
import { writeStream } from '../utils.js';
import { emitAtoms } from './atoms.js';
import { addEntityBoundsCliOptions, entityBoundsFromCli, } from './entity-bounds-command.js';
const RESUME_EXCLUSIVE_OPTIONS = [
    'ref',
    'since',
    'tokenizer',
    'formats',
    'maxCommits',
    'maxFilesPerCommit',
    'maxBlobBytes',
    'maxBlobLines',
    'maxTotalBlobBytes',
    'maxBatchBytes',
    'maxEntitiesPerFile',
    'maxEntitiesTotal',
    'maxLiveEntities',
    'maxLineageEvents',
    'maxCrossFileCandidates',
    'maxSimilarityCandidates',
];
/** Register the top-level source-body-free M4 episode stream. */
export function registerAtomsCommand(program) {
    const atoms = program
        .command('atoms')
        .description('Stream full-DAG, immutable code work episodes as NDJSON')
        .requiredOption('--path <repo-root>', 'repository root')
        .option('--ref <ref>', 'pinned commit to observe')
        .option('--since <ref>', 'emit only commits not reachable from this ancestor')
        .option('--resume <cursor>', 'resume an exact pinned run after one emitted edge')
        .addOption(new Option('--tokenizer <name>', 'exact tokenizer for changed patch payload')
        .choices(['o200k_base', 'cl100k_base'])
        .default('o200k_base'))
        .option('--no-formats', 'exclude JSON/YAML/TOML/CSV/Markdown entities')
        .option('--require-complete', 'exit nonzero when the footer reports incomplete coverage');
    addEntityBoundsCliOptions(atoms);
    atoms.action(async (options) => {
        try {
            if (options.resume && RESUME_EXCLUSIVE_OPTIONS.some(option => atoms.getOptionValueSource(option) === 'cli')) {
                throw new Error('--resume cannot be combined with ref, since, tokenizer, bounds, or format options.');
            }
            const request = {
                repoPath: path.resolve(options.path),
            };
            if (options.resume) {
                request.resume = options.resume;
            }
            else {
                if (options.ref)
                    request.ref = options.ref;
                if (options.since)
                    request.since = options.since;
                request.tokenizer = options.tokenizer === 'cl100k_base' ? 'cl100k_base' : 'o200k_base';
                request.formats = options.formats;
                request.bounds = entityBoundsFromCli(options);
            }
            let complete = false;
            for await (const event of emitAtoms(request)) {
                await writeStream(process.stdout, `${JSON.stringify(event)}\n`);
                if (event.type === 'footer')
                    complete = event.complete;
            }
            if (options.requireComplete && !complete)
                process.exitCode = 1;
        }
        catch (error) {
            process.exitCode = 1;
            await writeStream(process.stderr, `Error: ${error instanceof Error ? error.message : String(error)}\n`);
        }
    });
}
//# sourceMappingURL=atoms-command.js.map