"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CliOptionsSchema = exports.UnsupportedArgumentError = exports.UnknownArgumentError = exports.argMetadata = exports.defaultParserOptions = void 0;
exports.createParseArgs = createParseArgs;
exports.createParseArgsWithCliOptions = createParseArgsWithCliOptions;
exports.generateYargsOptionsFromSchema = generateYargsOptionsFromSchema;
exports.getLocale = getLocale;
const yargs_parser_1 = __importDefault(require("yargs-parser"));
const v4_1 = require("zod/v4");
const cli_options_1 = require("./cli-options");
const arg_metadata_1 = require("./arg-metadata");
Object.defineProperty(exports, "argMetadata", { enumerable: true, get: function () { return arg_metadata_1.argMetadata; } });
Object.defineProperty(exports, "UnknownArgumentError", { enumerable: true, get: function () { return arg_metadata_1.UnknownArgumentError; } });
Object.defineProperty(exports, "UnsupportedArgumentError", { enumerable: true, get: function () { return arg_metadata_1.UnsupportedArgumentError; } });
const utils_1 = require("./utils");
exports.defaultParserOptions = {
    configuration: {
        'camel-case-expansion': false,
        'unknown-options-as-args': true,
        'parse-positional-numbers': false,
        'parse-numbers': false,
        'greedy-arrays': false,
        'short-option-groups': false,
    },
};
function createParseArgs({ schema, parserOptions, }) {
    const options = generateYargsOptionsFromSchema({
        schema,
        parserOptions,
    });
    return ({ args }) => {
        const { argv, error } = yargs_parser_1.default.detailed(args, {
            ...options,
        });
        const { _: positional, ...parsedArgs } = argv;
        if (error) {
            if (error instanceof v4_1.ZodError) {
                throw new arg_metadata_1.InvalidArgumentError(error.message);
            }
            throw error;
        }
        const allDeprecatedArgs = (0, arg_metadata_1.getDeprecatedArgsWithReplacement)(schema);
        const usedDeprecatedArgs = {};
        for (const deprecated of Object.keys(allDeprecatedArgs)) {
            if (deprecated in parsedArgs) {
                const replacement = allDeprecatedArgs[deprecated];
                parsedArgs[replacement] =
                    parsedArgs[deprecated];
                usedDeprecatedArgs[deprecated] = replacement;
                delete parsedArgs[deprecated];
            }
        }
        for (const arg of positional) {
            if (typeof arg === 'string' && arg.startsWith('-')) {
                throw new arg_metadata_1.UnknownArgumentError(arg);
            }
        }
        const unsupportedArgs = (0, arg_metadata_1.getUnsupportedArgs)(schema);
        for (const unsupported of unsupportedArgs) {
            if (unsupported in parsedArgs) {
                throw new arg_metadata_1.UnsupportedArgumentError(unsupported);
            }
        }
        return {
            parsed: parsedArgs,
            deprecated: usedDeprecatedArgs,
            positional,
        };
    };
}
function createParseArgsWithCliOptions({ schema: schemaToExtend, parserOptions, } = {}) {
    const schema = schemaToExtend !== undefined
        ? v4_1.z.object({
            ...cli_options_1.CliOptionsSchema.shape,
            ...schemaToExtend.shape,
        })
        : cli_options_1.CliOptionsSchema;
    const parser = createParseArgs({
        schema,
        parserOptions,
    });
    return ({ args }) => {
        const { parsed, positional, deprecated } = parser({ args });
        const processed = (0, cli_options_1.processPositionalCliOptions)({
            parsed,
            positional,
        });
        (0, cli_options_1.validateCliOptions)(processed);
        return {
            parsed: processed,
            positional,
            deprecated,
        };
    };
}
function generateYargsOptionsFromSchema({ schema, parserOptions = exports.defaultParserOptions, }) {
    const options = {
        ...parserOptions,
        string: [],
        boolean: [],
        array: [],
        alias: {},
        coerce: {},
        number: [],
    };
    function processFields(currentSchema, prefix = '') {
        for (const [fieldName, fieldSchema] of Object.entries(currentSchema.shape)) {
            const fullFieldName = prefix ? `${prefix}.${fieldName}` : fieldName;
            const meta = (0, arg_metadata_1.getArgumentMetadata)(currentSchema, fieldName);
            const unwrappedType = (0, utils_1.unwrapType)(fieldSchema);
            if (unwrappedType instanceof v4_1.z.ZodArray) {
                options.array.push(fullFieldName);
            }
            else if (unwrappedType instanceof v4_1.z.ZodBoolean) {
                options.boolean.push(fullFieldName);
            }
            else if (unwrappedType instanceof v4_1.z.ZodString) {
                options.string.push(fullFieldName);
            }
            else if (unwrappedType instanceof v4_1.z.ZodNumber) {
                options.number.push(fullFieldName);
            }
            else if (unwrappedType instanceof v4_1.z.ZodUnion) {
                const unionOptions = unwrappedType.options;
                const hasString = unionOptions.some((opt) => opt instanceof v4_1.z.ZodString || opt instanceof v4_1.z.ZodEnum);
                if (hasString) {
                    const hasFalseLiteral = unionOptions.some((opt) => opt instanceof v4_1.z.ZodLiteral && opt.value === false);
                    const hasBoolean = unionOptions.some((opt) => opt instanceof v4_1.z.ZodBoolean);
                    if (hasFalseLiteral) {
                        options.coerce[fullFieldName] = utils_1.coerceIfFalse;
                        options.string.push(fullFieldName);
                    }
                    else if (hasBoolean) {
                        options.coerce[fullFieldName] = utils_1.coerceIfBoolean;
                    }
                    else {
                        options.string.push(fullFieldName);
                    }
                }
            }
            else if (unwrappedType instanceof v4_1.z.ZodEnum) {
                if (unwrappedType.options.every((opt) => typeof opt === 'string')) {
                    options.string.push(fullFieldName);
                }
                else if (unwrappedType.options.every((opt) => typeof opt === 'number')) {
                    options.number.push(fullFieldName);
                }
                else {
                    throw new Error(`${fullFieldName} has unsupported enum options. Currently, only string and number enum options are supported.`);
                }
            }
            else if (unwrappedType instanceof v4_1.z.ZodObject) {
                if (!prefix) {
                    options.coerce[fullFieldName] = (0, utils_1.coerceObject)(unwrappedType);
                }
                processFields(unwrappedType, fullFieldName);
            }
            else {
                throw new Error(`Unknown field type: ${unwrappedType instanceof Object
                    ? unwrappedType.constructor.name
                    : typeof unwrappedType}`);
            }
            if (!prefix && meta?.alias) {
                for (const a of meta.alias) {
                    options.alias[a] = fullFieldName;
                }
            }
        }
    }
    processFields(schema);
    return options;
}
function getLocale(args, env) {
    const localeIndex = args.indexOf('--locale');
    if (localeIndex > -1) {
        return args[localeIndex + 1];
    }
    const lang = env.LANG || env.LANGUAGE || env.LC_ALL || env.LC_MESSAGES;
    return lang ? lang.split('.')[0] : lang;
}
var cli_options_2 = require("./cli-options");
Object.defineProperty(exports, "CliOptionsSchema", { enumerable: true, get: function () { return cli_options_2.CliOptionsSchema; } });
//# sourceMappingURL=arg-parser.js.map