"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createCommandsManifestCommand = createCommandsManifestCommand;
const errors_1 = require("../../../lib/errors");
const output_1 = require("../../../lib/output");
async function createCommandsManifestCommand() {
    const { Command } = await import("commander");
    const command = new Command("manifest");
    command
        .description("Generate native tool descriptors from the authoritative command registry.")
        .argument("[command...]", "Optional exact command path for a single-tool manifest.")
        .option("--include-noncallable", "Include inspection-only metadata for descriptors outside the executable intersection.")
        .option("--input-json <json>", "Structured request object with optional command/includeNoncallable fields.")
        .action((segments, options, commandInstance) => {
        const format = (0, output_1.resolveOutputFormat)(commandInstance.optsWithGlobals?.().format);
        if (format === null)
            throw (0, errors_1.createUsageError)("Unsupported output format for commands manifest.");
        let normalized;
        try {
            if (options.inputJson !== undefined) {
                if (segments.length > 0 || options.includeNoncallable === true) {
                    throw new Error("--input-json cannot be combined with command arguments or --include-noncallable.");
                }
                const input = (0, output_1.parseStructuredCommandInput)(options.inputJson, ["command", "includeNoncallable"]);
                normalized = normalizeManifestRequest((0, output_1.requireStringArray)(input.command, "command", false), requireOptionalBoolean(input.includeNoncallable, "includeNoncallable"), "structured");
            }
            else {
                normalized = normalizeManifestRequest((0, output_1.requireStringArray)(segments, "command", false), options.includeNoncallable === true, "shell");
            }
        }
        catch (error) {
            throw (0, errors_1.createUsageError)(error instanceof Error ? error.message : "Invalid commands manifest request.");
        }
        const commandName = normalized.request.command.join(" ");
        let registry = output_1.COMMAND_DESCRIPTOR_REGISTRY;
        if (commandName.length > 0) {
            const descriptor = (0, output_1.getRegisteredCommandDescriptor)(commandName);
            if (descriptor === null) {
                throw (0, errors_1.createUsageError)(`Unknown command descriptor '${commandName}'.`, [
                    `Recovery: run day-shift commands search ${JSON.stringify(commandName)} --format json.`
                ]);
            }
            registry = [descriptor];
        }
        const runtimeCommands = (0, output_1.collectCallableCommandEvidence)(getRootCommand(commandInstance))
            .map((entry) => entry.command);
        const manifest = (0, output_1.createNativeToolManifest)(registry, {
            runtimeCommands,
            includeNonCallable: normalized.request.includeNoncallable || commandName.length > 0
        });
        (0, output_1.emitSuccess)({
            command: "commands manifest",
            format,
            data: { ...manifest, ...normalized },
            text: ({ data: projected }) => [
                `Native tool manifest: ${projected.tools.length} tool(s)`,
                ...projected.tools.map((tool) => `- ${tool.name}: ${tool.description}`),
                ...projected.inspectedNonCallable.map((descriptor) => `- ${descriptor.command}: ${descriptor.availability} (inspection only)`),
                (0, output_1.renderTerminalBoundary)({ kind: "read-only" })
            ].join("\n")
        });
    });
    return command;
}
function normalizeManifestRequest(command, includeNoncallable, inputStyle) {
    const segments = Object.freeze([...command]);
    return {
        request: Object.freeze({ command: segments, includeNoncallable }),
        requestArgv: Object.freeze([
            "day-shift", "commands", "manifest", ...segments,
            ...(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;
}
