import { writeFile } from 'node:fs/promises';
import { z } from 'zod';
import { formatBytes, formatPayloadJson, writeStream } from '../utils.js';
import { pruneOccCache } from './cache-management.js';
const CacheCommandOptionsSchema = z
    .object({
    cacheDir: z.string().optional(),
    maxAge: z.string().optional(),
    maxBytes: z.string().optional(),
    format: z.enum(['tabular', 'json']).optional(),
    output: z.string().optional(),
    pretty: z.boolean().optional(),
})
    .passthrough();
function parseMaxAge(value) {
    if (value == null)
        return undefined;
    const parsed = Number(value);
    if (!Number.isFinite(parsed) || parsed < 0) {
        throw new Error(`Invalid maximum age: "${value}" (expected non-negative days).`);
    }
    return parsed;
}
function parseMaxBytes(value) {
    if (value == null)
        return undefined;
    const parsed = Number(value);
    if (!Number.isSafeInteger(parsed) || parsed < 0) {
        throw new Error(`Invalid maximum bytes: "${value}" (expected a non-negative safe integer).`);
    }
    return parsed;
}
export function registerCacheCommand(program) {
    const cache = program.command('cache').description('Inspect and explicitly prune OCC persistent caches');
    const prune = cache
        .command('prune')
        .description('Remove superseded cache roots and entries outside optional age/size limits')
        .option('--cache-dir <path>', 'cache base (defaults outside the repository)')
        .option('--max-age <days>', 'remove entries not opened within this many days')
        .option('--max-bytes <n>', 'remove oldest entries until the cache uses at most n bytes')
        .option('--format <type>', 'output format: tabular or json', 'tabular')
        .option('-o, --output <file>', 'write output to file');
    prune.action(async () => {
        try {
            const options = CacheCommandOptionsSchema.parse(prune.optsWithGlobals());
            const result = await pruneOccCache({
                cacheDir: options.cacheDir,
                maxAgeDays: parseMaxAge(options.maxAge),
                maxBytes: parseMaxBytes(options.maxBytes),
            });
            const text = [
                `cache      ${result.root}`,
                `before     ${result.before.entryCount} entries, ${formatBytes(result.before.bytes)}`,
                `removed    ${result.removedEntries} entries, ${formatBytes(result.removedBytes)}`,
                `after      ${result.after.entryCount} entries, ${formatBytes(result.after.bytes)}`,
                ...(result.skippedOpenPaths.length > 0
                    ? [`protected  ${result.skippedOpenPaths.length} currently open path(s)`]
                    : []),
            ].join('\n');
            const rendered = `${options.format === 'json' ? formatPayloadJson(result, options.pretty) : text}\n`;
            if (options.output)
                await writeFile(options.output, rendered);
            else
                await writeStream(process.stdout, rendered);
        }
        catch (error) {
            await writeStream(process.stderr, `Error: ${error.message}\n`);
            process.exitCode = 1;
        }
    });
}
//# sourceMappingURL=cache-command.js.map