"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createCommandsSearchCommand = createCommandsSearchCommand;
const errors_1 = require("../../../lib/errors");
const output_1 = require("../../../lib/output");
async function createCommandsSearchCommand() {
    const { Command } = await import('commander');
    const command = new Command('search');
    command
        .description('Search authoritative command descriptors with bounded deterministic results.')
        .argument('[query]', 'Command identity, intent, capability, family, authorization, or posture query.')
        .option('--max-results <count>', 'Maximum results from 1 to 50.', '10')
        .option('--include-noncallable', 'Include reserved, planned, deprecated, and runtime-ineligible descriptors as inspection-only matches.')
        .option('--input-json <json>', 'Structured request object with query and optional maxResults/includeNoncallable.')
        .action((query, options, commandInstance) => {
        const format = (0, output_1.resolveOutputFormat)(commandInstance.optsWithGlobals?.().format);
        if (format === null)
            throw (0, errors_1.createUsageError)('Unsupported output format for commands search.');
        let normalized;
        let result;
        try {
            if (options.inputJson !== undefined) {
                if (query !== undefined ||
                    options.maxResults !== String(output_1.DEFAULT_COMMAND_SEARCH_LIMIT) ||
                    options.includeNoncallable === true) {
                    throw new Error('--input-json cannot be combined with query, --max-results, or --include-noncallable.');
                }
                const input = (0, output_1.parseStructuredCommandInput)(options.inputJson, ['query', 'maxResults', 'includeNoncallable']);
                const structuredQuery = (0, output_1.requireString)(input.query, 'query');
                const maxResults = (0, output_1.optionalBoundedInteger)(input.maxResults, 'maxResults', output_1.DEFAULT_COMMAND_SEARCH_LIMIT, 1, output_1.MAX_COMMAND_SEARCH_LIMIT);
                normalized = normalizeSearchRequest(structuredQuery, maxResults, requireOptionalBoolean(input.includeNoncallable, 'includeNoncallable'), 'structured');
            }
            else {
                normalized = normalizeSearchRequest((0, output_1.requireString)(query, 'query'), Number(options.maxResults), options.includeNoncallable === true, 'shell');
            }
            const root = getRootCommand(commandInstance);
            const runtimeCommands = (0, output_1.collectCallableCommandEvidence)(root).map((entry) => entry.command);
            result = (0, output_1.searchCommandDescriptors)(output_1.COMMAND_DESCRIPTOR_REGISTRY, normalized.request.query, normalized.request.maxResults, { includeNonCallable: normalized.request.includeNoncallable, runtimeCommands });
        }
        catch (error) {
            throw (0, errors_1.createUsageError)(error instanceof Error ? error.message : 'Invalid command search request.', [
                'Recovery: provide a non-empty query and --max-results from 1 to 50.',
            ]);
        }
        (0, output_1.emitSuccess)({
            command: 'commands search',
            format,
            data: { ...result, ...normalized },
            text: ({ data: projected }) => [
                `Command search: ${projected.query}`,
                ...projected.matches.map((entry) => `- ${entry.command}: ${entry.summary}`),
                (0, output_1.renderTerminalBoundary)({ kind: 'read-only' }),
            ].join('\n'),
        });
    });
    return command;
}
function normalizeSearchRequest(query, maxResults, includeNoncallable, inputStyle) {
    if (!Number.isInteger(maxResults) || maxResults < 1 || maxResults > output_1.MAX_COMMAND_SEARCH_LIMIT) {
        throw new Error(`Command search limit must be an integer from 1 to ${output_1.MAX_COMMAND_SEARCH_LIMIT}.`);
    }
    const normalizedQuery = query.trim();
    return {
        request: Object.freeze({ query: normalizedQuery, maxResults, includeNoncallable }),
        requestArgv: Object.freeze([
            'day-shift',
            'commands',
            'search',
            normalizedQuery,
            ...(maxResults === output_1.DEFAULT_COMMAND_SEARCH_LIMIT ? [] : ['--max-results', String(maxResults)]),
            ...(includeNoncallable ? ['--include-noncallable'] : []),
        ]),
        inputStyle,
    };
}
function requireOptionalBoolean(value, field) {
    if (value === undefined)
        return false;
    if (typeof value !== 'boolean')
        throw new Error(`${field} must be a boolean.`);
    return value;
}
function getRootCommand(commandInstance) {
    let root = commandInstance;
    while (root.parent !== null && root.parent !== undefined)
        root = root.parent;
    return root;
}
