// SPDX-License-Identifier: Apache-2.0
import * as constants from '../core/constants.js';
import * as version from '../../version.js';
import fs from 'node:fs';
import { IllegalArgumentError } from '../core/errors/illegal-argument-error.js';
import { SoloError } from '../core/errors/solo-error.js';
import { ListrInquirerPromptAdapter } from '@listr2/prompt-adapter-inquirer';
import { select as selectPrompt, input as inputPrompt, number as numberPrompt, confirm as confirmPrompt, } from '@inquirer/prompts';
import chalk from 'chalk';
import { PathEx } from '../business/utils/path-ex.js';
import validator from 'validator';
export class Flags {
    static KEY_COMMON = '_COMMON_';
    static async prompt(type, task, 
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    input, 
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    defaultValue, promptMessage, emptyCheckMessage, flagName) {
        try {
            let needsPrompt = type === 'toggle' ? input === undefined || typeof input !== 'boolean' : !input;
            needsPrompt = type === 'number' ? typeof input !== 'number' : needsPrompt;
            if (needsPrompt) {
                if (!process.stdout.isTTY || !process.stdin.isTTY) {
                    // this is to help find issues with prompts running in non-interactive mode, user should supply quite mode,
                    // or provide all flags required for command
                    throw new SoloError('Cannot prompt for input in non-interactive mode');
                }
                const promptOptions = { default: defaultValue, message: promptMessage };
                switch (type) {
                    case 'input': {
                        input = await task.prompt(ListrInquirerPromptAdapter).run(inputPrompt, promptOptions);
                        break;
                    }
                    case 'toggle': {
                        input = await task.prompt(ListrInquirerPromptAdapter).run(confirmPrompt, promptOptions);
                        break;
                    }
                    case 'number': {
                        input = await task.prompt(ListrInquirerPromptAdapter).run(numberPrompt, promptOptions);
                        break;
                    }
                }
            }
            if (emptyCheckMessage && !input) {
                throw new SoloError(emptyCheckMessage);
            }
            return input;
        }
        catch (error) {
            throw new SoloError(`input failed: ${flagName}: ${error.message}`, error);
        }
    }
    static async promptText(task, input, defaultValue, promptMessage, emptyCheckMessage, flagName) {
        return await Flags.prompt('input', task, input, defaultValue, promptMessage, emptyCheckMessage, flagName);
    }
    static async promptToggle(task, input, defaultValue, promptMessage, emptyCheckMessage, flagName) {
        return await Flags.prompt('toggle', task, input, defaultValue, promptMessage, emptyCheckMessage, flagName);
    }
    /**
     * Disable prompts for the given set of flags
     * @param flags list of flags to disable prompts for
     */
    static disablePrompts(flags) {
        Flags.resetDisabledPrompts();
        for (const flag of flags) {
            if (flag.definition) {
                flag.definition.disablePrompt = true;
            }
        }
    }
    /**
     * Set flag from the flag option
     * @param y instance of yargs
     * @param commandFlags a set of command flags
     *
     */
    static setRequiredCommandFlags(y, ...commandFlags) {
        // Check if help is being requested to avoid enforcing required flags
        const isHelpRequested = process.argv.includes('--help') || process.argv.includes('-h');
        for (const flag of commandFlags) {
            y.option(flag.name, { ...flag.definition, demandOption: !isHelpRequested });
        }
    }
    /**
     * Set flag from the flag option
     * @param y instance of yargs
     * @param commandFlags a set of command flags
     *
     */
    static setOptionalCommandFlags(y, ...commandFlags) {
        for (const flag of commandFlags) {
            const defaultValue = flag.definition.defaultValue === '' ? undefined : flag.definition.defaultValue;
            y.option(flag.name, {
                ...flag.definition,
                default: defaultValue,
            });
        }
    }
    static devMode = {
        constName: 'devMode',
        name: 'dev',
        definition: {
            describe: 'Enable developer mode',
            defaultValue: constants.SOLO_DEV_OUTPUT,
            type: 'boolean',
        },
        prompt: undefined,
    };
    static predefinedAccounts = {
        constName: 'predefinedAccounts',
        name: 'predefined-accounts',
        definition: {
            describe: 'Create predefined accounts on network creation',
            defaultValue: true,
            type: 'boolean',
        },
        prompt: undefined,
    };
    static forcePortForward = {
        constName: 'forcePortForward',
        name: 'force-port-forward',
        definition: {
            describe: 'Force port forward to access the network services',
            defaultValue: true, // always use local port-forwarding by default
            type: 'boolean',
        },
        prompt: undefined,
    };
    // list of common flags across commands. command specific flags are defined in the command's module.
    static clusterRef = {
        constName: 'clusterRef',
        name: 'cluster-ref',
        definition: {
            describe: 'The cluster reference that will be used for referencing the Kubernetes cluster and stored in the local and ' +
                'remote configuration for the deployment.  For commands that take multiple clusters they can be separated by commas.',
            alias: 'c',
            type: 'string',
        },
        prompt: async function promptClusterReference(task, input) {
            return await Flags.promptText(task, input, Flags.clusterRef.definition.defaultValue, 'Enter cluster reference: ', 'cluster reference cannot be empty', Flags.clusterRef.name);
        },
    };
    static clusterSetupNamespace = {
        constName: 'clusterSetupNamespace',
        name: 'cluster-setup-namespace',
        definition: {
            describe: 'Cluster Setup Namespace',
            defaultValue: constants.SOLO_SETUP_NAMESPACE.name,
            alias: 's',
            type: 'string',
        },
        prompt: async function promptClusterSetupNamespace(task, input) {
            return await Flags.promptText(task, input, 'solo-cluster', 'Enter cluster setup namespace name: ', 'cluster setup namespace cannot be empty', Flags.clusterSetupNamespace.name);
        },
    };
    static namespace = {
        constName: 'namespace',
        name: 'namespace',
        definition: {
            describe: 'Namespace',
            alias: 'n',
            type: 'string',
        },
        prompt: async function promptNamespace(task, input) {
            return await Flags.promptText(task, input, 'solo', 'Enter namespace name: ', 'namespace cannot be empty', Flags.namespace.name);
        },
    };
    static mirrorNamespace = {
        constName: 'mirrorNamespace',
        name: 'mirror-namespace',
        definition: {
            describe: 'Namespace to use for the Mirror Node deployment, a new one will be created if it does not exist',
            type: 'string',
        },
        prompt: undefined,
    };
    /**
     * Parse the values files input string that includes the cluster reference and the values file path
     * <p>It supports input as below:
     * <p>--values-file aws-cluster=aws/solo-values.yaml,aws-cluster=aws/solo-values2.yaml,gcp-cluster=gcp/solo-values.yaml,gcp-cluster=gcp/solo-values2.yaml
     * @param input
     */
    static parseValuesFilesInput(input) {
        const valuesFiles = {};
        if (input) {
            const inputItems = input.split(',');
            for (const v of inputItems) {
                const parts = v.split('=');
                let clusterReference;
                let valuesFile;
                if (parts.length === 2) {
                    clusterReference = parts[0];
                    valuesFile = PathEx.resolve(parts[1]);
                }
                else {
                    valuesFile = PathEx.resolve(v);
                    clusterReference = Flags.KEY_COMMON;
                }
                if (!valuesFiles[clusterReference]) {
                    valuesFiles[clusterReference] = [];
                }
                valuesFiles[clusterReference].push(valuesFile);
            }
        }
        return valuesFiles;
    }
    static valuesFile = {
        constName: 'valuesFile',
        name: 'values-file',
        definition: {
            describe: 'Comma separated chart values file',
            defaultValue: '',
            alias: 'f',
            type: 'string',
        },
        prompt: async function promptValuesFile(_, input) {
            return input; // no prompt is needed for values file
        },
    };
    static networkDeploymentValuesFile = {
        constName: 'valuesFile',
        name: 'values-file',
        definition: {
            describe: 'Comma separated chart values file paths for each cluster (e.g. values.yaml,cluster-1=./a/b/values1.yaml,cluster-2=./a/b/values2.yaml)',
            defaultValue: '',
            alias: 'f',
            type: 'string',
        },
        prompt: async function promptValuesFile(_, input) {
            if (input) {
                Flags.parseValuesFilesInput(input); // validate input as early as possible by parsing it
            }
            return input; // no prompt is needed for values file
        },
    };
    static profileFile = {
        constName: 'profileFile',
        name: 'profile-file',
        definition: {
            describe: 'Resource profile definition (e.g. custom-spec.yaml)',
            defaultValue: constants.DEFAULT_PROFILE_FILE,
            type: 'string',
        },
        prompt: async function promptProfileFile(task, input) {
            if (input && !fs.existsSync(input)) {
                input = await task.prompt(ListrInquirerPromptAdapter).run(inputPrompt, {
                    default: Flags.profileFile.definition.defaultValue,
                    message: 'Enter path to custom resource profile definition file: ',
                });
            }
            if (input && !fs.existsSync(input)) {
                throw new IllegalArgumentError(`Invalid profile definition file: ${input}}`, input);
            }
            return input;
        },
    };
    static profileName = {
        constName: 'profileName',
        name: 'profile',
        definition: {
            describe: `Resource profile (${constants.ALL_PROFILES.join(' | ')})`,
            defaultValue: constants.PROFILE_LOCAL,
            type: 'string',
        },
        prompt: async function promptProfile(task, input, choices = constants.ALL_PROFILES) {
            try {
                const initial = choices.indexOf(input);
                if (initial === -1) {
                    const input = (await task.prompt(ListrInquirerPromptAdapter).run(selectPrompt, {
                        message: 'Select profile for solo network deployment',
                        choices: structuredClone(choices).map((profile) => ({
                            name: profile,
                            value: profile,
                        })),
                    }));
                    if (!input) {
                        throw new SoloError('key-format cannot be empty');
                    }
                    return input;
                }
                return input;
            }
            catch (error) {
                throw new SoloError(`input failed: ${Flags.profileName.name}`, error);
            }
        },
    };
    static deployPrometheusStack = {
        constName: 'deployPrometheusStack',
        name: 'prometheus-stack',
        definition: {
            describe: 'Deploy prometheus stack',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: async function promptDeployPrometheusStack(task, input) {
            return await Flags.promptToggle(task, input, Flags.deployPrometheusStack.definition.defaultValue, 'Would you like to deploy prometheus stack? ', undefined, Flags.deployPrometheusStack.name);
        },
    };
    static deployGrafanaAgent = {
        constName: 'deployGrafanaAgent',
        name: 'grafana-agent',
        definition: {
            describe: 'Deploy grafana agent',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: async function promptDeployGrafanaAgent(task, input) {
            return await Flags.promptToggle(task, input, Flags.deployGrafanaAgent.definition.defaultValue, 'Would you like to deploy grafana agent? ', undefined, Flags.deployGrafanaAgent.name);
        },
    };
    static deployMinio = {
        constName: 'deployMinio',
        name: 'minio',
        definition: {
            describe: 'Deploy minio operator',
            defaultValue: true,
            type: 'boolean',
        },
        prompt: async function promptDeployMinio(task, input) {
            return await Flags.promptToggle(task, input, Flags.deployMinio.definition.defaultValue, 'Would you like to deploy MinIO? ', undefined, Flags.deployMinio.name);
        },
    };
    static deployCertManager = {
        constName: 'deployCertManager',
        name: 'cert-manager',
        definition: {
            describe: 'Deploy cert manager, also deploys acme-cluster-issuer',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: async function promptDeployCertManager(task, input) {
            return await Flags.promptToggle(task, input, Flags.deployCertManager.definition.defaultValue, 'Would you like to deploy Cert Manager? ', undefined, Flags.deployCertManager.name);
        },
    };
    /*
          Deploy cert manager CRDs separately from cert manager itself.  Cert manager
          CRDs are required for cert manager to deploy successfully.
   */
    static deployCertManagerCrds = {
        constName: 'deployCertManagerCrds',
        name: 'cert-manager-crds',
        definition: {
            describe: 'Deploy cert manager CRDs',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: async function promptDeployCertManagerCrds(task, input) {
            return await Flags.promptToggle(task, input, Flags.deployCertManagerCrds.definition.defaultValue, 'Would you like to deploy Cert Manager CRDs? ', undefined, Flags.deployCertManagerCrds.name);
        },
    };
    static deployJsonRpcRelay = {
        constName: 'deployJsonRpcRelay',
        name: 'json-rpc-relay',
        definition: {
            describe: 'Deploy JSON RPC Relay',
            defaultValue: false,
            alias: 'j',
            type: 'boolean',
        },
        prompt: undefined,
    };
    static stateFile = {
        constName: 'stateFile',
        name: 'state-file',
        definition: {
            describe: 'A zipped state file to be used for the network',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static upgradeZipFile = {
        constName: 'upgradeZipFile',
        name: 'upgrade-zip-file',
        definition: {
            describe: 'A zipped file used for network upgrade',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static releaseTag = {
        constName: 'releaseTag',
        name: 'release-tag',
        definition: {
            describe: `Release tag to be used (e.g. ${version.HEDERA_PLATFORM_VERSION})`,
            alias: 't',
            defaultValue: version.HEDERA_PLATFORM_VERSION,
            type: 'string',
        },
        prompt: async function promptReleaseTag(task, input) {
            return await Flags.promptText(task, input, version.HEDERA_PLATFORM_VERSION, 'Enter release version: ', undefined, Flags.releaseTag.name);
        },
    };
    static upgradeVersion = {
        constName: 'upgradeVersion',
        name: 'upgrade-version',
        definition: {
            describe: 'Version to be used for the upgrade',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static imageTag = {
        constName: 'imageTag',
        name: 'image-tag',
        definition: {
            describe: 'The Docker image tag to override what is in the Helm Chart',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static relayReleaseTag = {
        constName: 'relayReleaseTag',
        name: 'relay-release',
        definition: {
            describe: 'Relay release tag to be used (e.g. v0.48.0)',
            defaultValue: version.HEDERA_JSON_RPC_RELAY_VERSION,
            type: 'string',
        },
        prompt: async function promptRelayReleaseTag(task, input) {
            return await Flags.promptText(task, input, Flags.relayReleaseTag.definition.defaultValue, 'Enter relay release version: ', 'relay-release-tag cannot be empty', Flags.relayReleaseTag.name);
        },
    };
    static cacheDir = {
        constName: 'cacheDir',
        name: 'cache-dir',
        definition: {
            describe: 'Local cache directory',
            defaultValue: constants.SOLO_CACHE_DIR,
            type: 'string',
        },
        prompt: async function promptCacheDirectory(task, input) {
            return await Flags.promptText(task, input, constants.SOLO_CACHE_DIR, 'Enter local cache directory path: ', undefined, Flags.cacheDir.name);
        },
    };
    static nodeAliasesUnparsed = {
        constName: 'nodeAliasesUnparsed',
        name: 'node-aliases',
        definition: {
            describe: 'Comma separated node aliases (empty means all nodes)',
            alias: 'i',
            type: 'string',
        },
        prompt: async function promptNodeAliases(task, input) {
            return await Flags.prompt('input', task, input, 'node1,node2,node3', 'Enter list of node IDs (comma separated list): ', undefined, Flags.nodeAliasesUnparsed.name);
        },
    };
    static force = {
        constName: 'force',
        name: 'force',
        definition: {
            describe: 'Force actions even if those can be skipped',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: async function promptForce(task, input) {
            return await Flags.promptToggle(task, input, Flags.force.definition.defaultValue, 'Would you like to force changes? ', undefined, Flags.force.name);
        },
    };
    static chartDirectory = {
        constName: 'chartDirectory',
        name: 'chart-dir',
        definition: {
            describe: 'Local chart directory path (e.g. ~/solo-charts/charts)',
            defaultValue: '',
            type: 'string',
        },
        prompt: async function promptChartDirectory(task, input) {
            if (input === 'false') {
                return '';
            }
            try {
                if (input && !fs.existsSync(input)) {
                    input = await task.prompt(ListrInquirerPromptAdapter).run(inputPrompt, {
                        default: Flags.chartDirectory.definition.defaultValue,
                        message: 'Enter local charts directory path: ',
                    });
                    if (!fs.existsSync(input)) {
                        throw new IllegalArgumentError('Invalid chart directory', input);
                    }
                }
                return input;
            }
            catch (error) {
                throw new SoloError(`input failed: ${Flags.chartDirectory.name}`, error);
            }
        },
    };
    static relayChartDirectory = {
        constName: 'relayChartDirectory',
        name: 'relay-chart-dir',
        definition: {
            describe: 'Relay local chart directory path (e.g. ~/hiero-json-rpc-relay/charts)',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static explorerChartDirectory = {
        constName: 'explorerChartDirectory',
        name: 'explorer-chart-dir',
        definition: {
            describe: 'Explorer local chart directory path (e.g. ~/hiero-mirror-node-explorer/charts)',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static blockNodeChartDirectory = {
        constName: 'blockNodeChartDirectory',
        name: 'block-node-chart-dir',
        definition: {
            describe: 'Block node local chart directory path (e.g. ~/hiero-block-node/charts)',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static mirrorNodeChartDirectory = {
        constName: 'mirrorNodeChartDirectory',
        name: 'mirror-node-chart-dir',
        definition: {
            describe: 'Mirror node local chart directory path (e.g. ~/hiero-mirror-node/charts)',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static replicaCount = {
        constName: 'replicaCount',
        name: 'replica-count',
        definition: {
            describe: 'Replica count',
            defaultValue: 1,
            alias: '',
            type: 'number',
        },
        prompt: async function promptReplicaCount(task, input) {
            return await Flags.prompt('number', task, input, Flags.replicaCount.definition.defaultValue, 'How many replica do you want? ', undefined, Flags.replicaCount.name);
        },
    };
    static id = {
        constName: 'id',
        name: 'id',
        definition: {
            describe: 'The numeric identifier for the component',
            type: 'number',
        },
        prompt: async function (task, input) {
            return await Flags.prompt('number', task, input, undefined, 'Enter component id: ', undefined, Flags.id.name);
        },
    };
    static mirrorNodeId = {
        constName: 'mirrorNodeId',
        name: 'mirror-node-id',
        definition: {
            describe: 'The id of the mirror node which to connect',
            type: 'number',
        },
        prompt: async function (task, input) {
            return await Flags.prompt('number', task, input, undefined, 'Enter mirror node id: ', undefined, Flags.mirrorNodeId.name);
        },
    };
    static chainId = {
        constName: 'chainId',
        name: 'chain-id',
        definition: {
            describe: 'Chain ID',
            defaultValue: constants.HEDERA_CHAIN_ID, // Ref: https://github.com/hiero-ledger/hiero-json-rpc-relay#configuration
            alias: 'l',
            type: 'string',
        },
        prompt: async function promptChainId(task, input) {
            return await Flags.promptText(task, input, Flags.chainId.definition.defaultValue, 'Enter chain ID: ', undefined, Flags.chainId.name);
        },
    };
    // Ref: https://github.com/hiero-ledger/hiero-json-rpc-relay/blob/main/docs/configuration.md
    static operatorId = {
        constName: 'operatorId',
        name: 'operator-id',
        definition: {
            describe: 'Operator ID',
            defaultValue: undefined,
            type: 'string',
        },
        prompt: async function promptOperatorId(task, input) {
            return await Flags.promptText(task, input, Flags.operatorId.definition.defaultValue, 'Enter operator ID: ', undefined, Flags.operatorId.name);
        },
    };
    // Ref: https://github.com/hiero-ledger/hiero-json-rpc-relay/blob/main/docs/configuration.md
    static operatorKey = {
        constName: 'operatorKey',
        name: 'operator-key',
        definition: {
            describe: 'Operator Key',
            defaultValue: undefined,
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: async function promptOperatorKey(task, input) {
            return await Flags.promptText(task, input, Flags.operatorKey.definition.defaultValue, 'Enter operator private key: ', undefined, Flags.operatorKey.name);
        },
    };
    static privateKey = {
        constName: 'privateKey',
        name: 'private-key',
        definition: {
            describe: 'Show private key information',
            defaultValue: false,
            type: 'boolean',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: async function promptPrivateKey(task, input) {
            return await Flags.promptText(task, input, Flags.ed25519PrivateKey.definition.defaultValue, 'Enter the private key: ', undefined, Flags.ed25519PrivateKey.name);
        },
    };
    static generateGossipKeys = {
        constName: 'generateGossipKeys',
        name: 'gossip-keys',
        definition: {
            describe: 'Generate gossip keys for nodes',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: async function promptGenerateGossipKeys(task, input) {
            return await Flags.promptToggle(task, input, Flags.generateGossipKeys.definition.defaultValue, `Would you like to generate Gossip keys? ${typeof input} ${input} `, undefined, Flags.generateGossipKeys.name);
        },
    };
    static generateTlsKeys = {
        constName: 'generateTlsKeys',
        name: 'tls-keys',
        definition: {
            describe: 'Generate gRPC TLS keys for nodes',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: async function promptGenerateTLSKeys(task, input) {
            return await Flags.promptToggle(task, input, Flags.generateTlsKeys.definition.defaultValue, 'Would you like to generate TLS keys? ', undefined, Flags.generateTlsKeys.name);
        },
    };
    static enableTimeout = {
        constName: 'enableTimeout',
        name: 'enable-timeout',
        definition: {
            describe: 'enable time out for running a command',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: undefined,
    };
    static tlsClusterIssuerType = {
        constName: 'tlsClusterIssuerType',
        name: 'tls-cluster-issuer-type',
        definition: {
            describe: 'The TLS cluster issuer type to use for hedera explorer, defaults to "self-signed", the available options are: "acme-staging", "acme-prod", or "self-signed"',
            defaultValue: 'self-signed',
            type: 'string',
        },
        prompt: async function promptTlsClusterIssuerType(task, input) {
            if (input) {
                return;
            }
            try {
                input = (await task.prompt(ListrInquirerPromptAdapter).run(selectPrompt, {
                    default: Flags.tlsClusterIssuerType.definition.defaultValue,
                    message: 'Enter TLS cluster issuer type, available options are: "acme-staging", "acme-prod", or "self-signed":',
                    choices: ['acme-staging', 'acme-prod', 'self-signed'],
                }));
                return input;
            }
            catch (error) {
                throw new SoloError(`input failed: ${Flags.tlsClusterIssuerType.name}`, error);
            }
        },
    };
    static enableExplorerTls = {
        constName: 'enableExplorerTls',
        name: 'enable-explorer-tls',
        definition: {
            describe: 'Enable Explorer TLS, defaults to false, requires certManager and certManagerCrds, which can be deployed through solo-cluster-setup chart or standalone',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: async function promptEnableExplorerTls(task, input) {
            return await Flags.promptToggle(task, input, Flags.enableExplorerTls.definition.defaultValue, 'Would you like to enable the Explorer TLS? ', undefined, Flags.enableExplorerTls.name);
        },
    };
    static ingressControllerValueFile = {
        constName: 'ingressControllerValueFile',
        name: 'ingress-controller-value-file',
        definition: {
            describe: 'The value file to use for ingress controller, defaults to ""',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static explorerStaticIp = {
        constName: 'explorerStaticIp',
        name: 'explorer-static-ip',
        definition: {
            describe: 'The static IP address to use for the Explorer load balancer, defaults to ""',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static explorerTlsHostName = {
        constName: 'explorerTlsHostName',
        name: 'explorer-tls-host-name',
        definition: {
            describe: 'The host name to use for the Explorer TLS, defaults to "explorer.solo.local"',
            defaultValue: 'explorer.solo.local',
            type: 'string',
        },
        prompt: async function promptExplorerTlsHostName(task, input) {
            return await Flags.promptText(task, input, Flags.explorerTlsHostName.definition.defaultValue, 'Enter the host name to use for the Explorer TLS: ', undefined, Flags.explorerTlsHostName.name);
        },
    };
    static enableMonitoringSupport = {
        constName: 'enableMonitoringSupport',
        name: 'enable-monitoring-support',
        definition: {
            describe: 'Enables CRDs for Prometheus and Grafana.',
            defaultValue: true,
            type: 'boolean',
        },
        prompt: undefined,
    };
    static deletePvcs = {
        constName: 'deletePvcs',
        name: 'delete-pvcs',
        definition: {
            describe: 'Delete the persistent volume claims. If both --delete-pvcs and --delete-secrets are set to true, the namespace will be deleted.',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: async function promptDeletePvcs(task, input) {
            return await Flags.promptToggle(task, input, Flags.deletePvcs.definition.defaultValue, 'Would you like to delete persistent volume claims upon uninstall? ', undefined, Flags.deletePvcs.name);
        },
    };
    static deleteSecrets = {
        constName: 'deleteSecrets',
        name: 'delete-secrets',
        definition: {
            describe: 'Delete the network secrets. If both --delete-pvcs and --delete-secrets are set to true, the namespace will be deleted.',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: async function promptDeleteSecrets(task, input) {
            return await Flags.promptToggle(task, input, Flags.deleteSecrets.definition.defaultValue, 'Would you like to delete secrets upon uninstall? ', undefined, Flags.deleteSecrets.name);
        },
    };
    static soloChartVersion = {
        constName: 'soloChartVersion',
        name: 'solo-chart-version',
        definition: {
            describe: 'Solo testing chart version',
            defaultValue: version.SOLO_CHART_VERSION,
            type: 'string',
        },
        prompt: async function promptSoloChartVersion(task, input) {
            return await Flags.promptText(task, input, Flags.soloChartVersion.definition.defaultValue, 'Enter solo testing chart version: ', undefined, Flags.soloChartVersion.name);
        },
    };
    static blockNodeChartVersion = {
        constName: 'chartVersion',
        name: 'chart-version',
        definition: {
            describe: 'Block nodes chart version',
            defaultValue: version.BLOCK_NODE_VERSION,
            type: 'string',
        },
        prompt: undefined,
    };
    static blockNodeCfg = {
        constName: 'blockNodeCfg',
        name: 'block-node-cfg',
        definition: {
            describe: 'Configure block node routing for each consensus node. ' +
                'Maps consensus node names to block node IDs and optional priority (default priority = 1). ' +
                'Accepts: (1) JSON string: \'{"node1":["1=2","3=1"],"node2":["2"]}\' or (2) path to JSON file: \'block.json\'. ' +
                'Example: node1 sends blocks to block nodes 1 and 3, node2 sends blocks to block node 2',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static priorityMapping = {
        constName: 'priorityMapping',
        name: 'priority-mapping',
        definition: {
            describe: chalk.grey('Configure block node priority mapping') +
                chalk.blue('\n\t(Default: all consensus nodes included, first node priority is 2)') +
                chalk.yellow('\n\t[Format: <node>=<priority>[,<node>=<priority>]]') +
                chalk.yellow('\n\t[Example: "priority-mapping node1=2,node2=1"]') +
                chalk.red('\n\t[Unlisted nodes will not be routed to a block node]'),
            type: 'string',
        },
        prompt: undefined,
    };
    static externalBlockNodeAddress = {
        constName: 'externalBlockNodeAddress',
        name: 'address',
        definition: {
            describe: chalk.grey(`Provide external block node address ${chalk.grey('(IP or domain)')}, with optional port`) +
                chalk.blue(`\n\t(Default port: ${constants.BLOCK_NODE_PORT})`) +
                chalk.yellow('\n\t[Format: <address>[:<port>]]') +
                chalk.yellow('\n\t[Examples: "--address localhost:8080", "--address 192.0.0.1"]'),
            type: 'string',
        },
        prompt: undefined,
    };
    static applicationProperties = {
        constName: 'applicationProperties',
        name: 'application-properties',
        definition: {
            describe: 'application.properties file for node',
            defaultValue: PathEx.join('templates', 'application.properties'),
            type: 'string',
        },
        prompt: undefined,
    };
    static applicationEnv = {
        constName: 'applicationEnv',
        name: 'application-env',
        definition: {
            describe: 'the application.env file for the node provides environment variables to the solo-container' +
                ' to be used when the hedera platform is started',
            defaultValue: PathEx.join('templates', 'application.env'),
            type: 'string',
        },
        prompt: undefined,
    };
    static apiPermissionProperties = {
        constName: 'apiPermissionProperties',
        name: 'api-permission-properties',
        definition: {
            describe: 'api-permission.properties file for node',
            defaultValue: PathEx.join('templates', 'api-permission.properties'),
            type: 'string',
        },
        prompt: undefined,
    };
    static bootstrapProperties = {
        constName: 'bootstrapProperties',
        name: 'bootstrap-properties',
        definition: {
            describe: 'bootstrap.properties file for node',
            defaultValue: PathEx.join('templates', 'bootstrap.properties'),
            type: 'string',
        },
        prompt: undefined,
    };
    static genesisThrottlesFile = {
        constName: 'genesisThrottlesFile',
        name: 'genesis-throttles-file',
        definition: {
            describe: 'throttles.json file used during network genesis',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static settingTxt = {
        constName: 'settingTxt',
        name: 'settings-txt',
        definition: {
            describe: 'settings.txt file for node',
            defaultValue: PathEx.join('templates', 'settings.txt'),
            type: 'string',
        },
        prompt: undefined,
    };
    static app = {
        constName: 'app',
        name: 'app',
        definition: {
            describe: 'Testing app name',
            defaultValue: constants.HEDERA_APP_NAME,
            type: 'string',
        },
        prompt: undefined,
    };
    static appConfig = {
        constName: 'appConfig',
        name: 'app-config',
        definition: {
            describe: 'json config file of testing app',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static localBuildPath = {
        constName: 'localBuildPath',
        name: 'local-build-path',
        definition: {
            describe: 'path of hedera local repo',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static newAccountNumber = {
        constName: 'newAccountNumber',
        name: 'new-account-number',
        definition: {
            describe: 'new account number for node update transaction',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static newAdminKey = {
        constName: 'newAdminKey',
        name: 'new-admin-key',
        definition: {
            describe: 'new admin key for the Hedera account',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static gossipPublicKey = {
        constName: 'gossipPublicKey',
        name: 'gossip-public-key',
        definition: {
            describe: 'path and file name of the public key for signing gossip in PEM key format to be used',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static gossipPrivateKey = {
        constName: 'gossipPrivateKey',
        name: 'gossip-private-key',
        definition: {
            describe: 'path and file name of the private key for signing gossip in PEM key format to be used',
            defaultValue: '',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static tlsPublicKey = {
        constName: 'tlsPublicKey',
        name: 'tls-public-key',
        definition: {
            describe: 'path and file name of the public TLS key to be used',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static tlsPrivateKey = {
        constName: 'tlsPrivateKey',
        name: 'tls-private-key',
        definition: {
            describe: 'path and file name of the private TLS key to be used',
            defaultValue: '',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static log4j2Xml = {
        constName: 'log4j2Xml',
        name: 'log4j2-xml',
        definition: {
            describe: 'log4j2.xml file for node',
            defaultValue: PathEx.join('templates', 'log4j2.xml'),
            type: 'string',
        },
        prompt: undefined,
    };
    static updateAccountKeys = {
        constName: 'updateAccountKeys',
        name: 'update-account-keys',
        definition: {
            describe: 'Updates the special account keys to new keys and stores their keys in a corresponding Kubernetes secret',
            defaultValue: true,
            type: 'boolean',
        },
        prompt: async function promptUpdateAccountKeys(task, input) {
            return await Flags.promptToggle(task, input, Flags.updateAccountKeys.definition.defaultValue, 'Would you like to updates the special account keys to new keys and stores their keys in a corresponding Kubernetes secret? ', undefined, Flags.updateAccountKeys.name);
        },
    };
    static ed25519PrivateKey = {
        constName: 'ed25519PrivateKey',
        name: 'ed25519-private-key',
        definition: {
            describe: 'Specify a hex-encoded ED25519 private key for the Hedera account',
            defaultValue: '',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: async function promptPrivateKey(task, input) {
            return await Flags.promptText(task, input, Flags.ed25519PrivateKey.definition.defaultValue, 'Enter the private key: ', undefined, Flags.ed25519PrivateKey.name);
        },
    };
    static generateEcdsaKey = {
        constName: 'generateEcdsaKey',
        name: 'generate-ecdsa-key',
        definition: {
            describe: 'Generate ECDSA private key for the Hedera account',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: undefined,
    };
    static ecdsaPrivateKey = {
        constName: 'ecdsaPrivateKey',
        name: 'ecdsa-private-key',
        definition: {
            describe: 'Specify a hex-encoded ECDSA private key for the Hedera account',
            defaultValue: '',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: async function promptPrivateKey(task, input) {
            return await Flags.promptText(task, input, Flags.ed25519PrivateKey.definition.defaultValue, 'Enter the private key: ', undefined, Flags.ed25519PrivateKey.name);
        },
    };
    static setAlias = {
        constName: 'setAlias',
        name: 'set-alias',
        definition: {
            describe: 'Sets the alias for the Hedera account when it is created, requires --ecdsa-private-key',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: undefined,
    };
    static accountId = {
        constName: 'accountId',
        name: 'account-id',
        definition: {
            describe: 'The Hedera account id, e.g.: 0.0.1001',
            defaultValue: '',
            type: 'string',
        },
        prompt: async function promptAccountId(task, input) {
            return await Flags.promptText(task, input, Flags.accountId.definition.defaultValue, 'Enter the account id: ', undefined, Flags.accountId.name);
        },
    };
    static fileId = {
        constName: 'fileId',
        name: 'file-id',
        definition: {
            describe: 'The network file id, e.g.: 0.0.150',
            defaultValue: '',
            type: 'string',
        },
        prompt: async function promptFileId(task, input) {
            return await Flags.promptText(task, input, Flags.fileId.definition.defaultValue, 'Enter the file id: ', 'File ID cannot be empty', Flags.fileId.name);
        },
    };
    static filePath = {
        constName: 'filePath',
        name: 'file-path',
        definition: {
            describe: 'Local path to the file to upload',
            defaultValue: '',
            type: 'string',
        },
        prompt: async function promptFilePath(task, input) {
            return await Flags.promptText(task, input, Flags.filePath.definition.defaultValue, 'Enter the file path: ', 'File path cannot be empty', Flags.filePath.name);
        },
    };
    static amount = {
        constName: 'amount',
        name: 'hbar-amount',
        definition: {
            describe: 'Amount of HBAR to add',
            defaultValue: 100,
            type: 'number',
        },
        prompt: async function promptAmount(task, input) {
            return await Flags.prompt('number', task, input, Flags.amount.definition.defaultValue, 'How much HBAR do you want to add? ', undefined, Flags.amount.name);
        },
    };
    static createAmount = {
        constName: 'createAmount',
        name: 'create-amount',
        definition: {
            describe: 'Amount of new account to create',
            defaultValue: 1,
            type: 'number',
        },
        prompt: async function promptCreateAmount(task, input) {
            return await Flags.prompt('number', task, input, Flags.createAmount.definition.defaultValue, 'How many account to create? ', undefined, Flags.createAmount.name);
        },
    };
    static nodeAlias = {
        constName: 'nodeAlias',
        name: 'node-alias',
        definition: {
            describe: 'Node alias (e.g. node99)',
            type: 'string',
        },
        prompt: async function promptNewNodeAlias(task, input) {
            return await Flags.promptText(task, input, Flags.nodeAlias.definition.defaultValue, 'Enter the new node id: ', undefined, Flags.nodeAlias.name);
        },
    };
    static skipNodeAlias = {
        constName: 'skipNodeAlias',
        name: 'skip-node-alias',
        definition: {
            describe: 'The node alias to skip, because of a NodeUpdateTransaction or it is down (e.g. node99)',
            type: 'string',
        },
        prompt: async function promptNewNodeAlias(task, input) {
            return await Flags.promptText(task, input, Flags.skipNodeAlias.definition.defaultValue, 'Enter the node alias to skip: ', undefined, Flags.skipNodeAlias.name);
        },
    };
    static gossipEndpoints = {
        constName: 'gossipEndpoints',
        name: 'gossip-endpoints',
        definition: {
            describe: 'Comma separated gossip endpoints of the node(e.g. first one is internal, second one is external)',
            type: 'string',
        },
        prompt: async function promptGossipEndpoints(task, input) {
            return await Flags.promptText(task, input, Flags.gossipEndpoints.definition.defaultValue, 'Enter the gossip endpoints(comma separated): ', undefined, Flags.gossipEndpoints.name);
        },
    };
    static grpcEndpoints = {
        constName: 'grpcEndpoints',
        name: 'grpc-endpoints',
        definition: {
            describe: 'Comma separated gRPC endpoints of the node (at most 8)',
            type: 'string',
        },
        prompt: async function promptGrpcEndpoints(task, input) {
            return await Flags.promptText(task, input, Flags.grpcEndpoints.definition.defaultValue, 'Enter the gRPC endpoints(comma separated): ', undefined, Flags.grpcEndpoints.name);
        },
    };
    static endpointType = {
        constName: 'endpointType',
        name: 'endpoint-type',
        definition: {
            describe: 'Endpoint type (IP or FQDN)',
            defaultValue: constants.ENDPOINT_TYPE_FQDN,
            type: 'string',
        },
        prompt: async function promptEndpointType(task, input) {
            return await Flags.promptText(task, input, Flags.endpointType.definition.defaultValue, 'Enter the endpoint type(IP or FQDN): ', undefined, Flags.endpointType.name);
        },
    };
    static persistentVolumeClaims = {
        constName: 'persistentVolumeClaims',
        name: 'pvcs',
        definition: {
            describe: 'Enable persistent volume claims to store data outside the pod, required for consensus node add',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: async function promptPersistentVolumeClaims(task, input) {
            return await Flags.promptToggle(task, input, Flags.persistentVolumeClaims.definition.defaultValue, 'Would you like to enable persistent volume claims to store data outside the pod? ', undefined, Flags.persistentVolumeClaims.name);
        },
    };
    static debugNodeAlias = {
        constName: 'debugNodeAlias',
        name: 'debug-node-alias',
        definition: {
            describe: 'Enable default jvm debug port (5005) for the given node id',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static outputDir = {
        constName: 'outputDir',
        name: 'output-dir',
        definition: {
            describe: 'Path to the directory where the command context will be saved to',
            defaultValue: '',
            type: 'string',
        },
        prompt: async function promptOutputDirectory(task, input) {
            return await Flags.promptToggle(task, input, Flags.outputDir.definition.defaultValue, 'Enter path to directory to store the temporary context file', undefined, Flags.outputDir.name);
        },
    };
    static zipPassword = {
        constName: 'zipPassword',
        name: 'zip-password',
        definition: {
            describe: 'Password to encrypt generated backup ZIP archives',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static zipFile = {
        constName: 'zipFile',
        name: 'zip-file',
        definition: {
            describe: 'Path to the encrypted backup ZIP archive used during restore',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static inputDir = {
        constName: 'inputDir',
        name: 'input-dir',
        definition: {
            describe: 'Path to the directory where the command context will be loaded from',
            defaultValue: '',
            type: 'string',
        },
        prompt: async function promptInputDirectory(task, input) {
            return await Flags.promptToggle(task, input, Flags.inputDir.definition.defaultValue, 'Enter path to directory containing the temporary context file', undefined, Flags.inputDir.name);
        },
    };
    static optionsFile = {
        constName: 'optionsFile',
        name: 'options-file',
        definition: {
            describe: 'Path to YAML file containing component-specific deployment options (consensus, block, mirror, relay, explorer)',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static metallbConfig = {
        constName: 'metallbConfig',
        name: 'metallb-config',
        definition: {
            describe: 'Path pattern for MetalLB configuration YAML files (supports {index} placeholder for cluster number)',
            defaultValue: 'metallb-cluster-{index}.yaml',
            type: 'string',
        },
        prompt: undefined,
    };
    static adminKey = {
        constName: 'adminKey',
        name: 'admin-key',
        definition: {
            describe: 'Admin key',
            defaultValue: constants.GENESIS_KEY,
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static adminPublicKeys = {
        constName: 'adminPublicKeys',
        name: 'admin-public-keys',
        definition: {
            describe: 'Comma separated list of DER encoded ED25519 public keys and must match the order of the node aliases',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static quiet = {
        constName: 'quiet',
        name: 'quiet-mode',
        definition: {
            describe: 'Quiet mode, do not prompt for confirmation',
            defaultValue: false,
            alias: 'q',
            type: 'boolean',
            disablePrompt: true,
        },
        prompt: undefined,
    };
    static output = {
        constName: 'output',
        name: 'output',
        definition: {
            describe: 'Output format. One of: json|yaml|wide',
            defaultValue: '',
            alias: 'o',
            type: 'string',
            disablePrompt: true,
        },
        prompt: undefined,
    };
    static mirrorNodeVersion = {
        constName: 'mirrorNodeVersion',
        name: 'mirror-node-version',
        definition: {
            describe: 'Mirror node chart version',
            defaultValue: version.MIRROR_NODE_VERSION,
            type: 'string',
        },
        prompt: async function promptMirrorNodeVersion(task, input) {
            return await Flags.promptToggle(task, input, Flags.mirrorNodeVersion.definition.defaultValue, 'Would you like to choose mirror node version? ', undefined, Flags.mirrorNodeVersion.name);
        },
    };
    static enableIngress = {
        constName: 'enableIngress',
        name: 'enable-ingress',
        definition: {
            describe: 'enable ingress on the component/pod',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: undefined,
    };
    static mirrorStaticIp = {
        constName: 'mirrorStaticIp',
        name: 'mirror-static-ip',
        definition: {
            describe: 'static IP address for the mirror node',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static explorerVersion = {
        constName: 'explorerVersion',
        name: 'explorer-version',
        definition: {
            describe: 'Explorer chart version',
            defaultValue: version.EXPLORER_VERSION,
            type: 'string',
        },
        prompt: async function promptExplorerVersion(task, input) {
            return await Flags.promptToggle(task, input, Flags.explorerVersion.definition.defaultValue, 'Would you like to choose explorer version? ', undefined, Flags.explorerVersion.name);
        },
    };
    static context = {
        constName: 'context',
        name: 'context',
        definition: {
            describe: 'The Kubernetes context name to be used',
            defaultValue: '',
            type: 'string',
        },
        prompt: async function promptContext(task, input, cluster) {
            return (await task.prompt(ListrInquirerPromptAdapter).run(selectPrompt, {
                message: 'Select kubectl context' + (cluster ? ` to be associated with cluster: ${cluster}` : ''),
                choices: input,
            }));
        },
    };
    static deployment = {
        constName: 'deployment',
        name: 'deployment',
        definition: {
            describe: 'The name the user will reference locally to link to a deployment',
            alias: 'd',
            defaultValue: '',
            type: 'string',
        },
        prompt: async function promptDeployment(task, input) {
            return await Flags.promptText(task, input, Flags.deployment.definition.defaultValue, 'Enter the name of the deployment:', undefined, Flags.deployment.name);
        },
    };
    static deploymentClusters = {
        constName: 'deploymentClusters',
        name: 'deployment-clusters',
        definition: {
            describe: 'Solo deployment cluster list (comma separated)',
            type: 'string',
        },
        prompt: async function promptDeploymentClusters(task, input) {
            return await Flags.promptText(task, input, Flags.deploymentClusters.definition.defaultValue, 'Enter the Solo deployment cluster names (comma separated): ', undefined, Flags.deploymentClusters.name);
        },
    };
    static serviceMonitor = {
        constName: 'serviceMonitor',
        name: 'service-monitor',
        definition: {
            describe: 'Install ServiceMonitor custom resource for monitoring Network Node metrics',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: undefined,
    };
    static podLog = {
        constName: 'podLog',
        name: 'pod-log',
        definition: {
            describe: 'Install PodLog custom resource for monitoring Network Node pod logs',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: undefined,
    };
    static pinger = {
        constName: 'pinger',
        name: 'pinger',
        definition: {
            describe: 'Enable Pinger service in the Mirror node monitor',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: undefined,
    };
    //* ------------- Node Proxy Certificates ------------- !//
    static grpcTlsCertificatePath = {
        constName: 'grpcTlsCertificatePath',
        name: 'grpc-tls-cert',
        definition: {
            describe: 'TLS Certificate path for the gRPC ' +
                '(e.g. "node1=/Users/username/node1-grpc.cert" ' +
                'with multiple nodes comma separated)',
            defaultValue: '',
            type: 'string',
        },
        prompt: async function promptGrpcTlsCertificatePath(task, input) {
            return await Flags.promptText(task, input, Flags.grpcTlsCertificatePath.definition.defaultValue, 'Enter node alias and path to TLS certificate for gRPC (ex. nodeAlias=path )', undefined, Flags.grpcTlsCertificatePath.name);
        },
    };
    static grpcWebTlsCertificatePath = {
        constName: 'grpcWebTlsCertificatePath',
        name: 'grpc-web-tls-cert',
        definition: {
            describe: 'TLS Certificate path for gRPC Web ' +
                '(e.g. "node1=/Users/username/node1-grpc-web.cert" ' +
                'with multiple nodes comma separated)',
            defaultValue: '',
            type: 'string',
        },
        prompt: async function promptGrpcWebTlsCertificatePath(task, input) {
            return await Flags.promptText(task, input, Flags.grpcWebTlsCertificatePath.definition.defaultValue, 'Enter node alias and path to TLS certificate for gGRPC web (ex. nodeAlias=path )', undefined, Flags.grpcWebTlsCertificatePath.name);
        },
    };
    static useExternalDatabase = {
        constName: 'useExternalDatabase',
        name: 'use-external-database',
        definition: {
            describe: 'Set to true if you have an external database to use instead of the database that the Mirror Node Helm chart supplies',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: undefined,
    };
    //* ----------------- External Mirror Node PostgreSQL Database Related Flags ------------------ *//
    static externalDatabaseHost = {
        constName: 'externalDatabaseHost',
        name: 'external-database-host',
        definition: {
            describe: `Use to provide the external database host if the '--${Flags.useExternalDatabase.name}' is passed`,
            defaultValue: '',
            type: 'string',
        },
        prompt: async function promptGrpcWebTlsKeyPath(task, input) {
            return await Flags.promptText(task, input, Flags.externalDatabaseHost.definition.defaultValue, 'Enter host of the external database', undefined, Flags.externalDatabaseHost.name);
        },
    };
    static externalDatabaseOwnerUsername = {
        constName: 'externalDatabaseOwnerUsername',
        name: 'external-database-owner-username',
        definition: {
            describe: `Use to provide the external database owner's username if the '--${Flags.useExternalDatabase.name}' is passed`,
            defaultValue: '',
            type: 'string',
        },
        prompt: async function promptGrpcWebTlsKeyPath(task, input) {
            return await Flags.promptText(task, input, Flags.externalDatabaseOwnerUsername.definition.defaultValue, 'Enter username of the external database owner', undefined, Flags.externalDatabaseOwnerUsername.name);
        },
    };
    static externalDatabaseOwnerPassword = {
        constName: 'externalDatabaseOwnerPassword',
        name: 'external-database-owner-password',
        definition: {
            describe: `Use to provide the external database owner's password if the '--${Flags.useExternalDatabase.name}' is passed`,
            defaultValue: '',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: async function promptGrpcWebTlsKeyPath(task, input) {
            return await Flags.promptText(task, input, Flags.externalDatabaseOwnerPassword.definition.defaultValue, 'Enter password of the external database owner', undefined, Flags.externalDatabaseOwnerPassword.name);
        },
    };
    static externalDatabaseReadonlyUsername = {
        constName: 'externalDatabaseReadonlyUsername',
        name: 'external-database-read-username',
        definition: {
            describe: `Use to provide the external database readonly user's username if the '--${Flags.useExternalDatabase.name}' is passed`,
            defaultValue: '',
            type: 'string',
        },
        prompt: async function promptGrpcWebTlsKeyPath(task, input) {
            return await Flags.promptText(task, input, Flags.externalDatabaseReadonlyUsername.definition.defaultValue, 'Enter username of the external database readonly user', undefined, Flags.externalDatabaseReadonlyUsername.name);
        },
    };
    static externalDatabaseReadonlyPassword = {
        constName: 'externalDatabaseReadonlyPassword',
        name: 'external-database-read-password',
        definition: {
            describe: `Use to provide the external database readonly user's password if the '--${Flags.useExternalDatabase.name}' is passed`,
            defaultValue: '',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: async function promptGrpcWebTlsKeyPath(task, input) {
            return await Flags.promptText(task, input, Flags.externalDatabaseReadonlyPassword.definition.defaultValue, 'Enter password of the external database readonly user', undefined, Flags.externalDatabaseReadonlyPassword.name);
        },
    };
    //* ------------------------------------------------------------------------------------------- *//
    static username = {
        constName: 'username',
        name: 'user',
        definition: {
            describe: 'Optional user name used for local configuration. Only accepts letters and numbers. Defaults to the username provided by the OS',
            type: 'string',
            alias: 'u',
        },
        prompt: async function promptUsername(task, input) {
            const promptForInput = async () => {
                return await task.prompt(ListrInquirerPromptAdapter).run(inputPrompt, {
                    message: 'Please enter your username. Can only contain letters and numbers:',
                });
            };
            input = await promptForInput();
            while (!Flags.username.validate(input)) {
                input = await promptForInput();
            }
            return input;
        },
        validate: (input) => {
            // only allow letters and numbers
            return validator.isAlphanumeric(input);
        },
    };
    static grpcTlsKeyPath = {
        constName: 'grpcTlsKeyPath',
        name: 'grpc-tls-key',
        definition: {
            describe: 'TLS Certificate key path for the gRPC ' +
                '(e.g. "node1=/Users/username/node1-grpc.key" ' +
                'with multiple nodes comma separated)',
            defaultValue: '',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: async function promptGrpcTlsKeyPath(task, input) {
            return await Flags.promptText(task, input, Flags.grpcTlsKeyPath.definition.defaultValue, 'Enter node alias and path to TLS certificate key for gRPC (ex. nodeAlias=path )', undefined, Flags.grpcTlsKeyPath.name);
        },
    };
    static grpcWebTlsKeyPath = {
        constName: 'grpcWebTlsKeyPath',
        name: 'grpc-web-tls-key',
        definition: {
            describe: 'TLC Certificate key path for gRPC Web ' +
                '(e.g. "node1=/Users/username/node1-grpc-web.key" ' +
                'with multiple nodes comma separated)',
            defaultValue: '',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: async function promptGrpcWebTlsKeyPath(task, input) {
            return await Flags.promptText(task, input, Flags.grpcWebTlsKeyPath.definition.defaultValue, 'Enter node alias and path to TLS certificate key for gGRPC Web (ex. nodeAlias=path )', undefined, Flags.grpcWebTlsKeyPath.name);
        },
    };
    static stakeAmounts = {
        constName: 'stakeAmounts',
        name: 'stake-amounts',
        definition: {
            describe: 'The amount to be staked in the same order you list the node aliases with multiple node staked values comma separated',
            defaultValue: '',
            type: 'string',
        },
        prompt: undefined,
    };
    static haproxyIps = {
        constName: 'haproxyIps',
        name: 'haproxy-ips',
        definition: {
            describe: 'IP mapping where key = value is node alias and static ip for haproxy, ' +
                '(e.g.: --haproxy-ips node1=127.0.0.1,node2=127.0.0.1)',
            type: 'string',
        },
        prompt: undefined,
    };
    static envoyIps = {
        constName: 'envoyIps',
        name: 'envoy-ips',
        definition: {
            describe: 'IP mapping where key = value is node alias and static ip for envoy proxy, ' +
                '(e.g.: --envoy-ips node1=127.0.0.1,node2=127.0.0.1)',
            type: 'string',
        },
        prompt: undefined,
    };
    static storageType = {
        constName: 'storageType',
        name: 'storage-type',
        definition: {
            defaultValue: constants.StorageType.MINIO_ONLY,
            describe: 'storage type for saving stream files, available options are minio_only, aws_only, gcs_only, aws_and_gcs',
            type: 'StorageType',
        },
        prompt: undefined,
    };
    static gcsWriteAccessKey = {
        constName: 'gcsWriteAccessKey',
        name: 'gcs-write-access-key',
        definition: {
            defaultValue: '',
            describe: 'gcs storage access key for write access',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static gcsWriteSecrets = {
        constName: 'gcsWriteSecrets',
        name: 'gcs-write-secrets',
        definition: {
            defaultValue: '',
            describe: 'gcs storage secret key for write access',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static gcsEndpoint = {
        constName: 'gcsEndpoint',
        name: 'gcs-endpoint',
        definition: {
            defaultValue: '',
            describe: 'gcs storage endpoint URL',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static gcsBucket = {
        constName: 'gcsBucket',
        name: 'gcs-bucket',
        definition: {
            defaultValue: '',
            describe: 'name of gcs storage bucket',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static gcsBucketPrefix = {
        constName: 'gcsBucketPrefix',
        name: 'gcs-bucket-prefix',
        definition: {
            defaultValue: '',
            describe: 'path prefix of google storage bucket',
            type: 'string',
        },
        prompt: undefined,
    };
    static awsWriteAccessKey = {
        constName: 'awsWriteAccessKey',
        name: 'aws-write-access-key',
        definition: {
            defaultValue: '',
            describe: 'aws storage access key for write access',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static awsWriteSecrets = {
        constName: 'awsWriteSecrets',
        name: 'aws-write-secrets',
        definition: {
            defaultValue: '',
            describe: 'aws storage secret key for write access',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static awsEndpoint = {
        constName: 'awsEndpoint',
        name: 'aws-endpoint',
        definition: {
            defaultValue: '',
            describe: 'aws storage endpoint URL',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static awsBucket = {
        constName: 'awsBucket',
        name: 'aws-bucket',
        definition: {
            defaultValue: '',
            describe: 'name of aws storage bucket',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static awsBucketRegion = {
        constName: 'awsBucketRegion',
        name: 'aws-bucket-region',
        definition: {
            defaultValue: '',
            describe: 'name of aws bucket region',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static awsBucketPrefix = {
        constName: 'awsBucketPrefix',
        name: 'aws-bucket-prefix',
        definition: {
            defaultValue: '',
            describe: 'path prefix of aws storage bucket',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static backupBucket = {
        constName: 'backupBucket',
        name: 'backup-bucket',
        definition: {
            defaultValue: '',
            describe: 'name of bucket for backing up state files',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static backupWriteAccessKey = {
        constName: 'backupWriteAccessKey',
        name: 'backup-write-access-key',
        definition: {
            defaultValue: '',
            describe: 'backup storage access key for write access',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static backupWriteSecrets = {
        constName: 'backupWriteSecrets',
        name: 'backup-write-secrets',
        definition: {
            defaultValue: '',
            describe: 'backup storage secret key for write access',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static backupEndpoint = {
        constName: 'backupEndpoint',
        name: 'backup-endpoint',
        definition: {
            defaultValue: '',
            describe: 'backup storage endpoint URL',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static backupRegion = {
        constName: 'backupRegion',
        name: 'backup-region',
        definition: {
            defaultValue: 'us-central1',
            describe: 'backup storage region',
            type: 'string',
        },
        prompt: undefined,
    };
    static backupProvider = {
        constName: 'backupProvider',
        name: 'backup-provider',
        definition: {
            defaultValue: 'GCS',
            describe: 'backup storage service provider, GCS or AWS',
            type: 'string',
        },
        prompt: undefined,
    };
    static storageReadAccessKey = {
        constName: 'storageReadAccessKey',
        name: 'storage-read-access-key',
        definition: {
            defaultValue: '',
            describe: 'storage read access key for mirror node importer',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static storageReadSecrets = {
        constName: 'storageReadSecrets',
        name: 'storage-read-secrets',
        definition: {
            defaultValue: '',
            describe: 'storage read-secret key for mirror node importer',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static storageEndpoint = {
        constName: 'storageEndpoint',
        name: 'storage-endpoint',
        definition: {
            defaultValue: '',
            describe: 'storage endpoint URL for mirror node importer',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static storageBucket = {
        constName: 'storageBucket',
        name: 'storage-bucket',
        definition: {
            defaultValue: '',
            describe: 'name of storage bucket for mirror node importer',
            type: 'string',
            dataMask: constants.STANDARD_DATAMASK,
        },
        prompt: undefined,
    };
    static storageBucketPrefix = {
        constName: 'storageBucketPrefix',
        name: 'storage-bucket-prefix',
        definition: {
            defaultValue: '',
            describe: 'path prefix of storage bucket mirror node importer',
            type: 'string',
        },
        prompt: undefined,
    };
    static storageBucketRegion = {
        constName: 'storageBucketRegion',
        name: 'storage-bucket-region',
        definition: {
            defaultValue: '',
            describe: 'region of storage bucket mirror node importer',
            type: 'string',
        },
        prompt: undefined,
    };
    static loadBalancerEnabled = {
        constName: 'loadBalancerEnabled',
        name: 'load-balancer',
        definition: {
            describe: 'Enable load balancer for network node proxies',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: undefined,
    };
    // --------------- Add Cluster --------------- //
    static enableCertManager = {
        constName: 'enableCertManager',
        name: 'enable-cert-manager',
        definition: {
            describe: 'Pass the flag to enable cert manager',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: undefined,
    };
    static numberOfConsensusNodes = {
        constName: 'numberOfConsensusNodes',
        name: 'num-consensus-nodes',
        definition: {
            describe: 'Used to specify desired number of consensus nodes for pre-genesis deployments',
            type: 'number',
        },
        prompt: async function (task, input) {
            const promptForInput = () => Flags.prompt('number', task, input, Flags.numberOfConsensusNodes.definition.defaultValue, `Enter number of consensus nodes to add to the provided cluster ${chalk.grey('(must be a positive number)')}:`, undefined, Flags.numberOfConsensusNodes.name);
            input = await promptForInput();
            while (!input) {
                input = await promptForInput();
            }
            return input;
        },
    };
    static dnsBaseDomain = {
        constName: 'dnsBaseDomain',
        name: 'dns-base-domain',
        definition: {
            describe: 'Base domain for the DNS is the suffix used to construct the fully qualified domain name (FQDN)',
            defaultValue: 'cluster.local',
            type: 'string',
        },
        prompt: undefined,
    };
    static dnsConsensusNodePattern = {
        constName: 'dnsConsensusNodePattern',
        name: 'dns-consensus-node-pattern',
        definition: {
            describe: 'Pattern to construct the prefix for the fully qualified domain name (FQDN) for the consensus node, ' +
                'the suffix is provided by the --dns-base-domain option (ex. network-{nodeAlias}-svc.{namespace}.svc)',
            defaultValue: 'network-{nodeAlias}-svc.{namespace}.svc',
            type: 'string',
        },
        prompt: undefined,
    };
    static domainName = {
        constName: 'domainName',
        name: 'domain-name',
        definition: {
            describe: 'Custom domain name',
            type: 'string',
        },
        prompt: undefined,
    };
    static domainNames = {
        constName: 'domainNames',
        name: 'domain-names',
        definition: {
            describe: 'Custom domain names for consensus nodes mapping for the' +
                `${chalk.gray('(e.g. node0=domain.name where key is node alias and value is domain name)')}` +
                'with multiple nodes comma separated',
            type: 'string',
        },
        prompt: undefined,
    };
    static realm = {
        constName: 'realm',
        name: 'realm',
        definition: {
            describe: 'Realm number. Requires network-node > v61.0 for non-zero values',
            type: 'number',
            defaultValue: 0,
        },
        prompt: undefined,
    };
    static shard = {
        constName: 'shard',
        name: 'shard',
        definition: {
            describe: 'Shard number. Requires network-node > v61.0 for non-zero values',
            type: 'number',
            defaultValue: 0,
        },
        prompt: undefined,
    };
    // --------------- Rapid Fire --------------- //
    static maxTps = {
        constName: 'maxTps',
        name: 'max-tps',
        definition: {
            describe: 'The maximum transactions per second to be generated by the NLG load test',
            type: 'number',
            defaultValue: 0,
        },
        prompt: undefined,
    };
    static performanceTest = {
        constName: 'performanceTest',
        name: 'test',
        definition: {
            describe: 'The class name of the Performance Test to run',
            type: 'string',
            defaultValue: '',
        },
        prompt: undefined,
    };
    static packageName = {
        constName: 'packageName',
        name: 'package',
        definition: {
            describe: 'The package name of the Performance Test to run. Defaults to ',
            type: 'string',
            defaultValue: 'com.hedera.benchmark',
        },
        prompt: undefined,
    };
    static nlgArguments = {
        constName: 'nlgArguments',
        name: 'args',
        definition: {
            describe: 'All arguments to be passed to the NLG load test class. Value MUST be wrapped in 2 sets of different quotes. ' +
                'Example: \'"-c 100 -a 40 -t 3600"\'',
            type: 'string',
            defaultValue: '',
        },
        prompt: undefined,
    };
    static javaHeap = {
        constName: 'javaHeap',
        name: 'javaHeap',
        definition: {
            describe: 'Max Java heap size in GB for the NLG load test class, defaults to 8',
            type: 'number',
            defaultValue: 8,
        },
        prompt: undefined,
    };
    // --------------- One Shot --------------- //
    // A minimal setup deployment with 1 consensus node and 1 mirror node
    // Using this flag will enable one-shot to be used in a test workflow running on a default linux GitHub runner
    static minimalSetup = {
        constName: 'minimalSetup',
        name: 'minimal-setup',
        definition: {
            describe: 'Create a deployment with minimal setup. Only includes a single consensus node and mirror node',
            defaultValue: false,
            type: 'boolean',
        },
        prompt: undefined,
    };
    static allFlags = [
        Flags.accountId,
        Flags.fileId,
        Flags.filePath,
        Flags.adminKey,
        Flags.adminPublicKeys,
        Flags.amount,
        Flags.apiPermissionProperties,
        Flags.app,
        Flags.appConfig,
        Flags.applicationEnv,
        Flags.applicationProperties,
        Flags.bootstrapProperties,
        Flags.cacheDir,
        Flags.chainId,
        //* Chart directories
        Flags.chartDirectory,
        Flags.relayChartDirectory,
        Flags.explorerChartDirectory,
        Flags.blockNodeChartDirectory,
        Flags.mirrorNodeChartDirectory,
        Flags.clusterRef,
        Flags.clusterSetupNamespace,
        Flags.context,
        Flags.createAmount,
        Flags.debugNodeAlias,
        Flags.deletePvcs,
        Flags.deleteSecrets,
        Flags.deployCertManager,
        Flags.deployCertManagerCrds,
        Flags.deployJsonRpcRelay,
        Flags.deployMinio,
        Flags.deployPrometheusStack,
        Flags.deployGrafanaAgent,
        Flags.deployment,
        Flags.deploymentClusters,
        Flags.devMode,
        Flags.ecdsaPrivateKey,
        Flags.ed25519PrivateKey,
        Flags.enableIngress,
        Flags.enableExplorerTls,
        Flags.enableTimeout,
        Flags.endpointType,
        Flags.envoyIps,
        Flags.forcePortForward,
        Flags.generateEcdsaKey,
        Flags.generateGossipKeys,
        Flags.generateTlsKeys,
        Flags.genesisThrottlesFile,
        Flags.gossipEndpoints,
        Flags.gossipPrivateKey,
        Flags.gossipPublicKey,
        Flags.grpcEndpoints,
        Flags.grpcTlsCertificatePath,
        Flags.grpcTlsKeyPath,
        Flags.grpcWebTlsCertificatePath,
        Flags.grpcWebTlsKeyPath,
        Flags.haproxyIps,
        Flags.ingressControllerValueFile,
        Flags.explorerTlsHostName,
        Flags.explorerStaticIp,
        Flags.explorerVersion,
        Flags.inputDir,
        Flags.loadBalancerEnabled,
        Flags.localBuildPath,
        Flags.log4j2Xml,
        Flags.metallbConfig,
        Flags.mirrorNodeVersion,
        Flags.mirrorStaticIp,
        Flags.mirrorNamespace,
        Flags.namespace,
        Flags.networkDeploymentValuesFile,
        Flags.newAccountNumber,
        Flags.newAdminKey,
        Flags.nodeAlias,
        Flags.nodeAliasesUnparsed,
        Flags.operatorId,
        Flags.operatorKey,
        Flags.optionsFile,
        Flags.outputDir,
        Flags.persistentVolumeClaims,
        Flags.pinger,
        Flags.predefinedAccounts,
        Flags.privateKey,
        Flags.profileFile,
        Flags.profileName,
        Flags.quiet,
        Flags.output,
        Flags.imageTag,
        Flags.relayReleaseTag,
        Flags.releaseTag,
        Flags.upgradeVersion,
        Flags.replicaCount,
        Flags.setAlias,
        Flags.settingTxt,
        Flags.soloChartVersion,
        Flags.stakeAmounts,
        Flags.stateFile,
        Flags.storageType,
        Flags.gcsWriteAccessKey,
        Flags.gcsWriteSecrets,
        Flags.gcsEndpoint,
        Flags.gcsBucket,
        Flags.gcsBucketPrefix,
        Flags.awsWriteAccessKey,
        Flags.awsWriteSecrets,
        Flags.awsEndpoint,
        Flags.awsBucket,
        Flags.awsBucketRegion,
        Flags.awsBucketPrefix,
        Flags.storageReadAccessKey,
        Flags.storageReadSecrets,
        Flags.storageEndpoint,
        Flags.storageBucket,
        Flags.storageBucketPrefix,
        Flags.storageBucketRegion,
        Flags.backupBucket,
        Flags.backupWriteAccessKey,
        Flags.backupWriteSecrets,
        Flags.backupEndpoint,
        Flags.backupRegion,
        Flags.backupProvider,
        Flags.tlsClusterIssuerType,
        Flags.tlsPrivateKey,
        Flags.tlsPublicKey,
        Flags.updateAccountKeys,
        Flags.upgradeZipFile,
        Flags.valuesFile,
        Flags.useExternalDatabase,
        Flags.externalDatabaseHost,
        Flags.externalDatabaseOwnerUsername,
        Flags.externalDatabaseOwnerPassword,
        Flags.externalDatabaseReadonlyUsername,
        Flags.externalDatabaseReadonlyPassword,
        Flags.enableCertManager,
        Flags.numberOfConsensusNodes,
        Flags.dnsBaseDomain,
        Flags.dnsConsensusNodePattern,
        Flags.domainName,
        Flags.domainNames,
        Flags.blockNodeChartVersion,
        Flags.blockNodeCfg,
        Flags.priorityMapping,
        Flags.externalBlockNodeAddress,
        Flags.realm,
        Flags.shard,
        Flags.username,
        Flags.skipNodeAlias,
        Flags.id,
        Flags.mirrorNodeId,
        Flags.serviceMonitor,
        Flags.podLog,
        Flags.nlgArguments,
        Flags.javaHeap,
        Flags.performanceTest,
        Flags.packageName,
        Flags.minimalSetup,
        Flags.zipPassword,
        Flags.zipFile,
        Flags.maxTps,
        Flags.enableMonitoringSupport,
    ];
    /** Resets the definition.disablePrompt for all flags */
    static resetDisabledPrompts() {
        for (const f of Flags.allFlags) {
            if (f.definition.disablePrompt) {
                delete f.definition.disablePrompt;
            }
        }
    }
    static allFlagsMap = new Map(Flags.allFlags.map(f => [f.name, f]));
    static nodeConfigFileFlags = new Map([
        Flags.apiPermissionProperties,
        Flags.applicationEnv,
        Flags.applicationProperties,
        Flags.bootstrapProperties,
        Flags.log4j2Xml,
        Flags.settingTxt,
    ].map(f => [f.name, f]));
    static integerFlags = new Map([Flags.replicaCount].map(f => [f.name, f]));
    static DEFAULT_FLAGS = {
        required: [],
        optional: [Flags.namespace, Flags.cacheDir, Flags.releaseTag, Flags.devMode, Flags.quiet],
    };
    /**
     * Processes the Argv arguments and returns them as string, all with full flag names.
     * - removes flags that match the default value.
     * - removes flags with undefined and null values.
     * - removes boolean flags that are false.
     * - masks all sensitive flags with their dataMask property.
     */
    static stringifyArgv(argv) {
        const processedFlags = [];
        for (const [name, value] of Object.entries(argv)) {
            // Remove non-flag data and boolean presence based flags that are false
            if (name === '_' || name === '$0' || value === '' || value === false || value === undefined || value === null) {
                continue;
            }
            // remove flags that use the default value
            const flag = Flags.allFlags.find(flag => flag.name === name);
            if (!flag || (flag.definition.defaultValue && flag.definition.defaultValue === value)) {
                continue;
            }
            const flagName = flag.name;
            // if the flag is boolean based, render it without value
            if (value === true) {
                processedFlags.push(`--${flagName}`);
            }
            // if the flag's data is masked, display it without the value
            else if (flag.definition.dataMask) {
                processedFlags.push(`--${flagName} ${flag.definition.dataMask}`);
            }
            // else display the full flag data
            else {
                processedFlags.push(`--${flagName} ${value}`);
            }
        }
        return processedFlags.join(' ');
    }
}
//# sourceMappingURL=flags.js.map