/**
 * Copyright (c) Microsoft Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import * as z from 'zod';
import { commands } from './commands';
function commandArgs(command) {
    const args = [];
    const shape = command.args ? command.args.shape : {};
    for (const [name, schema] of Object.entries(shape)) {
        const zodSchema = schema;
        const description = zodSchema.description ?? '';
        args.push({ name, description, optional: zodSchema.safeParse(undefined).success });
    }
    return args;
}
function commandArgsText(args) {
    return args.map(a => a.optional ? `[${a.name}]` : `<${a.name}>`).join(' ');
}
function generateCommandHelp(command) {
    const args = commandArgs(command);
    const lines = [
        `playwright-cli ${command.name} ${commandArgsText(args)}`,
        '',
        command.description,
        '',
    ];
    if (args.length) {
        lines.push('Arguments:');
        lines.push(...args.map(a => formatWithGap(`  ${a.optional ? `[${a.name}]` : `<${a.name}>`}`, a.description.toLowerCase())));
    }
    if (command.options) {
        lines.push('Options:');
        const optionsShape = command.options.shape;
        for (const [name, schema] of Object.entries(optionsShape)) {
            const zodSchema = schema;
            const description = (zodSchema.description ?? '').toLowerCase();
            lines.push(formatWithGap(`  --${name}`, description));
        }
    }
    return lines.join('\n');
}
const categories = [
    { name: 'core', title: 'Core' },
    { name: 'navigation', title: 'Navigation' },
    { name: 'keyboard', title: 'Keyboard' },
    { name: 'mouse', title: 'Mouse' },
    { name: 'export', title: 'Save as' },
    { name: 'tabs', title: 'Tabs' },
    { name: 'storage', title: 'Storage' },
    { name: 'network', title: 'Network' },
    { name: 'devtools', title: 'DevTools' },
    { name: 'install', title: 'Install' },
    { name: 'config', title: 'Configuration' },
    { name: 'browsers', title: 'Browser sessions' },
];
export function generateHelp() {
    const lines = [];
    lines.push('Usage: playwright-cli <command> [args] [options]');
    lines.push('Usage: playwright-cli -s=<session> <command> [args] [options]');
    const commandsByCategory = new Map();
    for (const c of categories)
        commandsByCategory.set(c.name, []);
    for (const command of Object.values(commands)) {
        if (command.hidden)
            continue;
        commandsByCategory.get(command.category).push(command);
    }
    for (const c of categories) {
        const cc = commandsByCategory.get(c.name);
        if (!cc.length)
            continue;
        lines.push(`\n${c.title}:`);
        for (const command of cc)
            lines.push(generateHelpEntry(command));
    }
    lines.push('\nGlobal options:');
    lines.push(formatWithGap('  --help [command]', 'print help'));
    lines.push(formatWithGap('  --json', 'output response as JSON'));
    lines.push(formatWithGap('  --raw', 'output only the result value, without status and code'));
    lines.push(formatWithGap('  --version', 'print version'));
    return lines.join('\n');
}
export function generateReadme() {
    const lines = [];
    lines.push('\n## Commands');
    const commandsByCategory = new Map();
    for (const c of categories)
        commandsByCategory.set(c.name, []);
    for (const command of Object.values(commands))
        commandsByCategory.get(command.category).push(command);
    for (const c of categories) {
        const cc = commandsByCategory.get(c.name);
        if (!cc.length)
            continue;
        lines.push(`\n### ${c.title}\n`);
        lines.push('```bash');
        for (const command of cc)
            lines.push(generateReadmeEntry(command));
        lines.push('```');
    }
    return lines.join('\n');
}
function generateHelpEntry(command) {
    const args = commandArgs(command);
    const prefix = `  ${command.name} ${commandArgsText(args)}`;
    const suffix = command.description.toLowerCase();
    return formatWithGap(prefix, suffix);
}
function generateReadmeEntry(command) {
    const args = commandArgs(command);
    const prefix = `playwright-cli ${command.name} ${commandArgsText(args)}`;
    const suffix = '# ' + command.description.toLowerCase();
    return formatWithGap(prefix, suffix, 40);
}
function unwrapZodType(schema) {
    if ('unwrap' in schema && typeof schema.unwrap === 'function')
        return unwrapZodType(schema.unwrap());
    return schema;
}
function isBooleanSchema(schema) {
    return unwrapZodType(schema) instanceof z.ZodBoolean;
}
export function generateHelpJSON() {
    const booleanOptions = new Set();
    const commandEntries = {};
    for (const [name, command] of Object.entries(commands)) {
        const flags = {};
        if (command.options) {
            const optionsShape = command.options.shape;
            for (const [flagName, schema] of Object.entries(optionsShape)) {
                const isBoolean = isBooleanSchema(schema);
                flags[flagName] = isBoolean ? 'boolean' : 'string';
                if (isBoolean)
                    booleanOptions.add(flagName);
            }
        }
        const args = command.args ? Object.keys(command.args.shape) : [];
        commandEntries[name] = { help: generateCommandHelp(command), flags, args };
        if (command.raw)
            commandEntries[name].raw = true;
    }
    return {
        global: generateHelp(),
        commands: commandEntries,
        booleanOptions: [...booleanOptions],
    };
}
function formatWithGap(prefix, text, threshold = 30) {
    const indent = Math.max(1, threshold - prefix.length);
    return prefix + ' '.repeat(indent) + text;
}
//# sourceMappingURL=helpGenerator.js.map