import { exitCodeDescriptions } from "./errors.js";
import { parseArgsSchema, parseOptionsSchema } from "./schema-parser.js";
import * as z from 'zod';
/**
 * Apply args, options, and response from a CommandSchemas to a SchemaCommand.
 * Shared by both extractCommandSchema and extractSubcommandSchema.
 */
function applySchemaFields(schema, schemas) {
    if (schemas.args) {
        const parsedArgs = parseArgsSchema(schemas.args);
        schema.arguments = parsedArgs.metadata.map((arg) => ({
            name: arg.name,
            type: arg.variadic ? 'array' : 'string',
            required: !arg.optional,
            variadic: arg.variadic,
        }));
    }
    if (schemas.options) {
        const parsedOptions = parseOptionsSchema(schemas.options);
        schema.options = parsedOptions.map((opt) => ({
            name: opt.name,
            type: opt.type,
            required: !opt.hasDefault,
            default: opt.defaultValue,
            description: opt.description,
        }));
    }
    if (schemas.response) {
        schema.response = z.toJSONSchema(schemas.response);
    }
}
/**
 * Extract schema information from a CommandDefinition
 */
export function extractCommandSchema(def) {
    const schema = {
        name: def.name,
        description: def.description,
    };
    if (def.aliases) {
        schema.aliases = def.aliases;
    }
    // Extract examples if available
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    if (def.examples) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        schema.examples = def.examples;
    }
    // Extract idempotent marker
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    if (def.idempotent !== undefined) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        schema.idempotent = def.idempotent;
    }
    // Extract prerequisites
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    if (def.prerequisites) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        schema.prerequisites = def.prerequisites;
    }
    // Extract pagination
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    if (def.pagination) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        schema.pagination = def.pagination;
    }
    // Extract tags
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    if (def.tags) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        schema.tags = def.tags;
    }
    // Extract skipSkill
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    if (def.skipSkill !== undefined) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        schema.skipSkill = def.skipSkill;
    }
    // Extract requires/optional
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const d = def;
    if (d.requires) {
        schema.requires = {
            auth: d.requires.auth === true,
            project: d.requires.project === true,
            org: d.requires.org === true,
            region: d.requires.region === true,
            regions: d.requires.regions === true,
        };
    }
    if (d.optional) {
        schema.optional = {
            auth: d.optional.auth === true || typeof d.optional.auth === 'string',
            project: d.optional.project === true,
            org: d.optional.org === true,
            region: d.optional.region === true,
        };
    }
    // Extract args and options from schema if available
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    if (def.schema) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const schemas = def.schema;
        applySchemaFields(schema, schemas);
    }
    // Extract subcommands recursively
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    if (def.subcommands) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        schema.subcommands = def.subcommands.map((sub) => extractSubcommandSchema(sub));
    }
    return schema;
}
/**
 * Extract schema information from a SubcommandDefinition
 */
export function extractSubcommandSchema(def) {
    const schema = {
        name: def.name,
        description: def.description,
    };
    if (def.aliases) {
        schema.aliases = def.aliases;
    }
    // Extract examples if available
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    if (def.examples) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        schema.examples = def.examples;
    }
    // Extract idempotent marker
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    if (def.idempotent !== undefined) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        schema.idempotent = def.idempotent;
    }
    // Extract prerequisites
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    if (def.prerequisites) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        schema.prerequisites = def.prerequisites;
    }
    // Extract pagination
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    if (def.pagination) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        schema.pagination = def.pagination;
    }
    // Extract tags
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    if (def.tags) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        schema.tags = def.tags;
    }
    // Extract skipSkill
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    if (def.skipSkill !== undefined) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        schema.skipSkill = def.skipSkill;
    }
    // Extract toplevel
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    if (def.toplevel !== undefined) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        schema.toplevel = def.toplevel;
    }
    // Extract requires/optional
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const d = def;
    if (d.requires) {
        schema.requires = {
            auth: d.requires.auth === true,
            project: d.requires.project === true,
            org: d.requires.org === true,
            region: d.requires.region === true,
            regions: d.requires.regions === true,
        };
    }
    if (d.optional) {
        schema.optional = {
            auth: d.optional.auth === true || typeof d.optional.auth === 'string',
            project: d.optional.project === true,
            org: d.optional.org === true,
            region: d.optional.region === true,
        };
    }
    // Extract args and options from schema if available
    if (d.schema) {
        const schemas = d.schema;
        applySchemaFields(schema, schemas);
    }
    // Extract nested subcommands recursively
    if (d.subcommands) {
        schema.subcommands = d.subcommands.map((sub) => extractSubcommandSchema(sub));
    }
    return schema;
}
/**
 * Generate JSON schema for the entire CLI
 */
export function generateCLISchema(_program, commands, version) {
    const schema = {
        name: 'agentuity',
        version,
        description: 'Agentuity CLI',
        exitCodes: { ...exitCodeDescriptions },
        globalOptions: [
            {
                name: 'config',
                type: 'string',
                required: false,
                description: 'Config file path',
            },
            {
                name: 'log-level',
                type: 'string',
                required: false,
                default: 'info',
                description: 'Log level',
                enum: ['debug', 'trace', 'info', 'warn', 'error'],
            },
            {
                name: 'log-timestamp',
                type: 'boolean',
                required: false,
                default: false,
                description: 'Show timestamps in log output',
            },
            {
                name: 'log-prefix',
                type: 'boolean',
                required: false,
                default: true,
                description: 'Show log level prefixes',
            },
            {
                name: 'org-id',
                type: 'string',
                required: false,
                description: 'Use a specific organization when performing operations (alias: --org)',
            },
            {
                name: 'color-scheme',
                type: 'string',
                required: false,
                description: 'Color scheme: light or dark',
                enum: ['light', 'dark'],
            },
            {
                name: 'color',
                type: 'string',
                required: false,
                default: 'auto',
                description: 'Color output: auto, always, never',
                enum: ['auto', 'always', 'never'],
            },
            {
                name: 'error-format',
                type: 'string',
                required: false,
                default: 'text',
                description: 'Error output format: json or text',
                enum: ['json', 'text'],
            },
            {
                name: 'json',
                type: 'boolean',
                required: false,
                default: false,
                description: 'Output in JSON format (machine-readable)',
            },
            {
                name: 'quiet',
                type: 'boolean',
                required: false,
                default: false,
                description: 'Suppress non-essential output',
            },
            {
                name: 'no-progress',
                type: 'boolean',
                required: false,
                default: false,
                description: 'Disable progress indicators',
            },
            {
                name: 'explain',
                type: 'boolean',
                required: false,
                default: false,
                description: 'Show what the command would do without executing',
            },
            {
                name: 'dry-run',
                type: 'boolean',
                required: false,
                default: false,
                description: 'Execute command without making changes',
            },
            {
                name: 'validate',
                type: 'boolean',
                required: false,
                default: false,
                description: 'Validate arguments and options without executing',
            },
            {
                name: 'input',
                type: 'string',
                required: false,
                description: 'Pass arguments and options as a JSON object (for agents)',
            },
            {
                name: 'describe',
                type: 'boolean',
                required: false,
                default: false,
                description: 'Output command schema as JSON for agent introspection',
            },
            {
                name: 'fields',
                type: 'string',
                required: false,
                description: 'Filter JSON output to specified fields (comma-separated, dot notation for nested)',
            },
        ],
        commands: commands.map(extractCommandSchema),
    };
    return schema;
}
//# sourceMappingURL=schema-generator.js.map