"use strict";
/**
 * 🏎️ NATIVE CLI PARSER - COMMANDER DESTROYER
 * Zero-dependency argument parsing
 *
 * "The ONE thing commander was doing - we do it BETTER!"
 * DC VICTORY #3 INCOMING!
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.Command = exports.program = exports.NativeCliParser = void 0;
/**
 * 🚀 The FAF CLI Parser - Championship Grade
 */
class NativeCliParser {
    commands = new Map();
    globalOptions = [];
    versionString = '';
    descriptionText = '';
    programName = 'cli';
    // Short flag mappings (e.g., -q -> quiet)
    shortFlags = new Map();
    constructor() {
        // Add default help option
        this.globalOptions.push({
            flags: '-h, --help',
            description: 'display help for command',
            type: 'boolean'
        });
    }
    /**
     * Set CLI name (commander compatibility)
     */
    name(nameStr) {
        this.programName = nameStr;
        return this;
    }
    setName(nameStr) {
        this.programName = nameStr;
        return this;
    }
    /**
     * Set CLI description
     */
    description(desc) {
        this.descriptionText = desc;
        return this;
    }
    setDescription(desc) {
        return this.description(desc);
    }
    /**
     * Set version
     */
    version(ver) {
        this.versionString = ver;
        if (!this.globalOptions.some(opt => opt.flags.includes('--version'))) {
            this.globalOptions.push({
                flags: '-V, --version',
                description: 'output the version number',
                type: 'boolean'
            });
        }
        return this;
    }
    setVersion(ver) {
        return this.version(ver);
    }
    /**
     * Add help text (commander compatibility)
     */
    addHelpText(position, text) {
        // For now, we'll just store this but not display it
        // Could be enhanced later to actually show the text
        return this;
    }
    /**
     * Add a global option
     */
    option(flags, description, defaultValue) {
        const option = {
            flags,
            description,
            defaultValue,
            type: defaultValue === undefined ? 'boolean' : typeof defaultValue
        };
        this.globalOptions.push(option);
        this.parseFlags(flags);
        return this;
    }
    /**
     * Add a command
     */
    command(nameAndArgs) {
        const [name, ...argDefs] = nameAndArgs.split(' ');
        const command = {
            name,
            fullSignature: nameAndArgs, // Store full signature for optional arg detection
            description: '',
            options: []
        };
        this.commands.set(name, command);
        // Return a builder that also has parser methods for chaining
        return new CommandBuilder(command, this);
    }
    /**
     * Parse flags string to extract short/long mappings
     */
    parseFlags(flags) {
        // Parse "-q, --quiet" or "--force"
        const parts = flags.split(',').map(s => s.trim());
        let shortFlag = '';
        let longFlag = '';
        for (const part of parts) {
            if (part.startsWith('--')) {
                longFlag = part.slice(2).split(/[\s<\[]/)[0];
            }
            else if (part.startsWith('-')) {
                shortFlag = part.slice(1).split(/[\s<\[]/)[0];
            }
        }
        if (shortFlag && longFlag) {
            this.shortFlags.set(shortFlag, longFlag);
        }
    }
    /**
     * 🎯 THE CORE PARSER - This is what commander was doing!
     */
    parse(argv = process.argv) {
        const args = argv.slice(2); // Skip node and script
        const result = {
            command: null,
            options: {},
            args: [],
            rawArgs: args
        };
        // Set defaults for global options
        for (const opt of this.globalOptions) {
            if (opt.defaultValue !== undefined) {
                const key = this.extractLongFlag(opt.flags);
                result.options[key] = opt.defaultValue;
            }
        }
        let i = 0;
        let stopParsing = false; // For -- handling
        // Parse all arguments
        while (i < args.length) {
            const arg = args[i];
            // Handle -- separator
            if (arg === '--') {
                stopParsing = true;
                i++;
                // Everything after -- goes into args
                while (i < args.length) {
                    result.args.push(args[i++]);
                }
                break;
            }
            // If we're past --, just collect args
            if (stopParsing) {
                result.args.push(arg);
                i++;
                continue;
            }
            // If no command yet and this isn't a flag, it's the command
            if (!result.command && !arg.startsWith('-')) {
                result.command = arg;
                i++;
                continue;
            }
            if (arg.startsWith('--')) {
                // Long flag: --force or --template=svelte
                const equalIndex = arg.indexOf('=');
                if (equalIndex > -1) {
                    // --key=value format
                    const key = arg.slice(2, equalIndex);
                    const value = arg.slice(equalIndex + 1);
                    result.options[key] = this.parseValue(value);
                }
                else {
                    const key = arg.slice(2);
                    // Handle --no-* flags (e.g., --no-show sets show: false)
                    if (key.startsWith('no-')) {
                        const actualKey = key.slice(3);
                        result.options[actualKey] = false;
                    }
                    else {
                        // Check if next arg is the value (and it's not a negative number that looks like a flag)
                        if (i + 1 < args.length) {
                            const nextArg = args[i + 1];
                            // Check if next arg is a value (not a flag, unless it's a negative number)
                            if (!nextArg.startsWith('-') || /^-\d/.test(nextArg)) {
                                result.options[key] = this.parseValue(args[++i]);
                            }
                            else {
                                // Boolean flag
                                result.options[key] = true;
                            }
                        }
                        else {
                            // Boolean flag
                            result.options[key] = true;
                        }
                    }
                }
            }
            else if (arg.startsWith('-') && !/^-\d/.test(arg)) {
                // Short flag(s): -q or -qf (multiple flags)
                const flags = arg.slice(1);
                for (let j = 0; j < flags.length; j++) {
                    const shortFlag = flags[j];
                    const longFlag = this.shortFlags.get(shortFlag) || shortFlag;
                    // Check if this is the last flag and next arg might be value
                    if (j === flags.length - 1 &&
                        i + 1 < args.length &&
                        !args[i + 1].startsWith('-')) {
                        // Could be a value
                        const nextArg = args[i + 1];
                        // Simple heuristic: if the flag typically takes a value, consume it
                        if (!this.isBooleanFlag(longFlag)) {
                            result.options[longFlag] = this.parseValue(args[++i]);
                        }
                        else {
                            result.options[longFlag] = true;
                        }
                    }
                    else {
                        // Boolean flag
                        result.options[longFlag] = true;
                    }
                }
            }
            else {
                // Positional argument
                result.args.push(arg);
            }
            i++;
        }
        // Handle special flags
        if (result.options.version) {
            console.log(this.versionString);
            process.exit(0);
        }
        if (result.options.help) {
            this.showHelp(result.command);
            process.exit(0);
        }
        return result;
    }
    /**
     * Execute parsed command
     *
     * 🏁 FIXED: Commander standard is args first, options last!
     */
    async execute(parsed) {
        if (!parsed.command) {
            this.showHelp();
            return;
        }
        const command = this.commands.get(parsed.command);
        if (!command) {
            console.error(`Error: unknown command '${parsed.command}'`);
            this.showHelp();
            process.exit(1);
        }
        if (command.action) {
            // ✅ FIXED: Pass positional args first, then options (Commander standard)
            // Check if required args are missing
            if (command.fullSignature?.includes('<') && parsed.args.length === 0) {
                // Command has required args but none provided
                console.error(`Error: missing required argument for '${parsed.command}'`);
                this.showHelp(parsed.command);
                process.exit(1);
            }
            // For commands with optional positional args like [term], we need to pass undefined
            // when no args provided, so options object goes in correct position
            if (parsed.args.length === 0 && command.fullSignature?.includes('[')) {
                // Command has optional positional args but none provided
                await command.action(undefined, parsed.options);
            }
            else {
                await command.action(...parsed.args, parsed.options);
            }
        }
    }
    /**
     * Parse and execute in one call (like commander's parse())
     */
    async run(argv = process.argv) {
        const parsed = this.parse(argv);
        await this.execute(parsed);
    }
    /**
     * Show help text
     */
    showHelp(commandName) {
        if (commandName && this.commands.has(commandName)) {
            const command = this.commands.get(commandName);
            console.log(`\nUsage: ${this.programName} ${command.name} [options]`);
            console.log(`\n${command.description}`);
            if (command.options && command.options.length > 0) {
                console.log('\nOptions:');
                for (const opt of command.options) {
                    console.log(`  ${opt.flags.padEnd(25)} ${opt.description}`);
                }
            }
        }
        else {
            // Show general help
            console.log(`Usage: ${this.programName} [options] [command]`);
            console.log(`\n${this.descriptionText}`);
            console.log('\nOptions:');
            for (const opt of this.globalOptions) {
                const flags = opt.flags.padEnd(25);
                const desc = opt.defaultValue !== undefined
                    ? `${opt.description} (default: "${opt.defaultValue}")`
                    : opt.description;
                console.log(`  ${flags} ${desc}`);
            }
            if (this.commands.size > 0) {
                console.log('\nCommands:');
                for (const [name, cmd] of this.commands) {
                    console.log(`  ${name.padEnd(25)} ${cmd.description}`);
                }
                console.log(`\nRun '${this.programName} <command> --help' for command details`);
            }
        }
    }
    /**
     * Helper to parse values (string, number, boolean)
     */
    parseValue(value) {
        if (value === 'true')
            return true;
        if (value === 'false')
            return false;
        // Handle negative numbers and positive numbers
        if (/^-?\d+$/.test(value))
            return parseInt(value, 10);
        if (/^-?\d*\.\d+$/.test(value))
            return parseFloat(value);
        return value;
    }
    /**
     * Check if flag is typically boolean
     */
    isBooleanFlag(flag) {
        // Common boolean flags
        const booleanFlags = ['quiet', 'force', 'help', 'version', 'verbose', 'debug', 'color'];
        return booleanFlags.includes(flag);
    }
    /**
     * Extract long flag from flags string
     */
    extractLongFlag(flags) {
        const match = flags.match(/--([a-z-]+)/i);
        return match ? match[1] : flags;
    }
    /**
     * Get parsed options (for compatibility)
     */
    opts() {
        const parsed = this.parse();
        return parsed.options;
    }
    /**
     * Action method (commander compatibility)
     */
    action(fn) {
        // Store action at the program level
        this.programAction = fn;
        return this;
    }
    programAction;
    /**
     * Show help (commander compatibility)
     */
    help() {
        // Return help text as string
        const lines = [];
        lines.push(`Usage: ${this.programName} [options] [command]`);
        lines.push(`\n${this.descriptionText}`);
        lines.push('\nOptions:');
        for (const opt of this.globalOptions) {
            const flags = opt.flags.padEnd(25);
            const desc = opt.defaultValue !== undefined
                ? `${opt.description} (default: "${opt.defaultValue}")`
                : opt.description;
            lines.push(`  ${flags} ${desc}`);
        }
        if (this.commands.size > 0) {
            lines.push('\nCommands:');
            for (const [name, cmd] of this.commands) {
                lines.push(`  ${name.padEnd(25)} ${cmd.description}`);
            }
        }
        return lines.join('\n');
    }
}
exports.NativeCliParser = NativeCliParser;
/**
 * Command Builder for fluent API
 */
class CommandBuilder {
    command;
    parser;
    constructor(command, parser) {
        this.command = command;
        this.parser = parser;
    }
    description(desc) {
        this.command.description = desc;
        return this;
    }
    option(flags, description, defaultValue) {
        this.command.options = this.command.options || [];
        this.command.options.push({
            flags,
            description,
            defaultValue,
            type: defaultValue === undefined ? 'boolean' : typeof defaultValue
        });
        return this;
    }
    action(fn) {
        this.command.action = fn;
        return this;
    }
    alias(alias) {
        this.command.aliases = this.command.aliases || [];
        this.command.aliases.push(alias);
        return this;
    }
    addHelpText(position, text) {
        // Commander compatibility - store but don't display for now
        return this;
    }
}
/**
 * 🏁 Export a singleton instance for drop-in replacement
 */
exports.program = new NativeCliParser();
/**
 * Export the class as Command for compatibility
 */
exports.Command = NativeCliParser;
/**
 * DC VICTORY STATUS:
 *
 * ✅ Parses all flag formats
 * ✅ Maps short to long flags
 * ✅ Handles values (string/number/boolean)
 * ✅ Generates help text
 * ✅ Routes commands
 * ✅ Drop-in commander replacement
 * ✅ FIXED: Correct argument order (args first, options last)
 *
 * Total lines: ~300 (vs 9,500 bytes of commander)
 * Dependencies: ZERO
 *
 * COMMANDER IS GOING DOWN! 🎯
 */
//# sourceMappingURL=native-cli-parser.js.map