import { Command as Base } from '@oclif/core/command';
import * as Flags from '@oclif/core/flags';
import { APIClient } from './api-client.js';
export class Command extends Base {
    /**
     * Base flags that includes the prompt flag by default
     * Subclasses can override this to customize base flags
     */
    static baseFlags = {
        prompt: Flags.boolean({
            description: 'interactively prompt for command arguments and flags',
            helpGroup: 'GLOBAL',
        }),
    };
    /**
     * Set this to false in a command class to disable the --prompt flag for that command
     */
    static promptFlagActive = true;
    _heroku;
    allowArbitraryFlags = false;
    /**
     * Helper function to get baseFlags without the prompt flag
     * Use this when you want to remove the prompt flag in a specific command:
     *
     * @example
     * export default class MyCommand extends Command {
     *   static baseFlags = Command.baseFlagsWithoutPrompt()
     *   static flags = { ... }
     * }
     */
    static baseFlagsWithoutPrompt() {
        // Destructure to remove the prompt flag
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        const { prompt, ...rest } = this.baseFlags;
        return rest;
    }
    get heroku() {
        if (this._heroku)
            return this._heroku;
        const options = {
            debug: process.env.HEROKU_DEBUG === '1' || process.env.HEROKU_DEBUG?.toUpperCase() === 'TRUE',
            debugHeaders: process.env.HEROKU_DEBUG_HEADERS === '1' || process.env.HEROKU_DEBUG_HEADERS?.toUpperCase() === 'TRUE',
        };
        this._heroku = new APIClient(this.config, options);
        return this._heroku;
    }
    async init() {
        await super.init();
        if (!this.isPromptModeActive()) {
            return;
        }
        // Check if --prompt flag is present in argv
        if (!this.argv.includes('--prompt')) {
            return;
        }
        // If we get here, we need to prompt for inputs
        const commandId = this.id;
        if (!commandId)
            return;
        const { promptAndRun } = await import('./prompt.js');
        await promptAndRun({
            argv: this.argv,
            commandId,
            config: this.config,
        });
    }
    /**
     * Returns whether prompt mode is active for this command.
     * False if the command has opted out (static promptFlagActive = false)
     * or if the prompt flag is not in baseFlags.
     */
    isPromptModeActive() {
        const Ctor = this.constructor;
        return Ctor.promptFlagActive && ('prompt' in Ctor.baseFlags);
    }
    async parse(options, argv) {
        if (this.allowArbitraryFlags) {
            try {
                return await super.parse(options, argv);
            }
            catch (error) {
                const parser = (await import('yargs-parser')).default;
                const unparser = (await import('yargs-unparser')).default;
                const { flags: nonExistentFlags } = error;
                const parsed = parser(this.argv);
                const nonExistentFlagsWithValues = { ...parsed };
                if (nonExistentFlags && nonExistentFlags.length > 0) {
                    this.warn(`You're using a deprecated syntax with the [${nonExistentFlags}] flag.\nAdd a '--' (end of options) separator before the flags you're passing through.`);
                    for (const flag of nonExistentFlags) {
                        const key = flag.replace('--', '');
                        delete parsed[key];
                    }
                }
                for (const key in parsed) {
                    if (Reflect.has(parsed, key)) {
                        delete nonExistentFlagsWithValues[key];
                    }
                }
                this.argv = unparser(parsed);
                const result = await super.parse(options, argv);
                result.nonExistentFlags = unparser(nonExistentFlagsWithValues);
                for (let index = 0; index < result.nonExistentFlags.length; index++) {
                    const positionalValue = result.nonExistentFlags[index];
                    const doubleHyphenRegex = /^--/;
                    const positionalValueIsFlag = doubleHyphenRegex.test(positionalValue);
                    if (positionalValueIsFlag) {
                        const nextElement = result.nonExistentFlags[index + 1] ?? '';
                        const nextElementIsFlag = doubleHyphenRegex.test(nextElement);
                        // eslint-disable-next-line max-depth
                        if (nextElement && !nextElementIsFlag) {
                            result.argv.push(`${positionalValue}=${nextElement}`);
                        }
                        else if (!nextElement || nextElementIsFlag) {
                            result.argv.push(`${positionalValue}=${true}`);
                        }
                    }
                }
                return result;
            }
        }
        return super.parse(options, argv);
    }
}
