"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.addUpdateEnvCommands = addUpdateEnvCommands;
const mablApi_1 = require("@mablhq-internal/runtime/mablApi");
const mablApiClientFactory_1 = require("@mablhq-internal/runtime/api/mablApiClientFactory");
const constants_1 = require("@mablhq-internal/runtime/core/constants");
const constants_2 = require("../../constants");
const util_1 = require("../../commandUtil/util");
const cliUtil_1 = require("@mablhq-internal/runtime/core/cliUtil");
const branches_1 = require("@mablhq-internal/runtime/util/branches/branches");
const chalk_1 = __importDefault(require("chalk"));
const loggingProvider_1 = require("@mablhq-internal/runtime/providers/logging/loggingProvider");
const add_1 = require("./urls_cmds/add");
const environmentsValidation_1 = require("@mablhq-internal/runtime/core/entityValidation/environmentsValidation");
exports.command = 'create';
exports.describe = 'Create a new mabl environment';
exports.builder = (yargs) => {
    addUpdateEnvCommands((0, add_1.addEnvironmentUrlOptions)(yargs), true)
        .option(constants_1.CommandArgWorkspaceId, {
        alias: constants_2.CommandArgAliases.WorkspaceId,
        describe: 'Workspace containing to create environment in',
        nargs: 1,
        type: 'string',
    })
        .option(constants_1.CommandArgApplicationId, {
        describe: 'Id of application to associate with this environment',
        nargs: 1,
        type: 'string',
    })
        .option(constants_2.CommandArgUrlApp, {
        describe: 'Web application URLs to associate with the application-environment pair',
        type: 'array',
    })
        .option(constants_1.CommandArgUrlApi, {
        describe: 'API URLs to associate with the application-environment pair',
        type: 'array',
    });
};
exports.handler = (0, cliUtil_1.failWrapper)(createEnvironment);
function addUpdateEnvCommands(argv, isCreate) {
    return argv
        .option(constants_2.CommandArgName, {
        alias: constants_2.CommandArgAliases.Name,
        demandOption: isCreate,
        describe: 'Name of the environment',
        nargs: 1,
        type: 'string',
    })
        .option(constants_2.CommandArgDescription, {
        describe: 'Description of the environment',
        nargs: 1,
        type: 'string',
    })
        .option(constants_2.CommandArgVariables, {
        describe: 'Key-value environment variable pairs of the form var1:value1',
        type: 'array',
        default: [],
    })
        .option(constants_2.CommandArgLinkLabel, {
        describe: 'Name of link agent to use for this environment',
        nargs: 1,
        type: 'string',
    })
        .option(constants_2.CommandArgLinkBypass, {
        describe: 'Set to true to bypass the mabl http proxy.  Only supported if running over a link agent.',
        boolean: true,
        hidden: true,
        default: false,
    })
        .option(constants_1.CommandArgMablBranch, {
        describe: 'Name of mabl branch to associated with this environment.  Tests run against this environment will use the version on this branch.',
        nargs: 1,
        type: 'string',
    })
        .option(constants_2.CommandArgPreview, {
        describe: 'Set to true to mark this as an preview environment',
        boolean: true,
        default: false,
    })
        .check((argv) => {
        const branchName = argv[constants_1.CommandArgMablBranch];
        if (branchName !== undefined && !(0, branches_1.isValidMablBranchName)(branchName)) {
            throw new Error(`[${branchName}] is not a valid mabl branch name. Please specify a valid name`);
        }
        return true;
    })
        .coerce('variables', (variables) => {
        if (variables.length === 0) {
            return undefined;
        }
        (0, util_1.validateArrayInputs)(variables, 'Variables must be SPACE delimited, e.g. --variables foo:bar baz:qux');
        const validVariables = (0, util_1.validateValuePairInputs)('Variable', variables);
        return validVariables.reduce((variablesObject, item) => {
            const { name, value } = (0, util_1.parseColonJoinedVariablePair)(item);
            variablesObject[name] = value;
            return variablesObject;
        }, {});
    })
        .check((argv) => {
        const variables = argv[constants_2.CommandArgVariables];
        if (!variables) {
            return true;
        }
        const variableNames = Object.keys(variables);
        const invalidVariableNames = variableNames.filter((name) => !(0, environmentsValidation_1.isValidEnvironmentVariableName)(name));
        if (invalidVariableNames.length === 0) {
            return true;
        }
        const maybePlural = invalidVariableNames.length > 1 ? 's' : '';
        throw new Error(`Invalid environment variable name${maybePlural}: ${invalidVariableNames.join(', ')}. Environment variable names must start with a letter or underscore and contain only letters, numbers, and underscores.`);
    });
}
async function createEnvironment(parsed) {
    let environment;
    try {
        const apiClient = await mablApiClientFactory_1.MablApiClientFactory.createApiClient();
        let workspaceId;
        try {
            workspaceId = await (0, util_1.getWorkspaceId)(parsed);
        }
        catch {
        }
        environment = {
            organization_id: workspaceId,
            name: parsed[constants_2.CommandArgName],
            description: parsed[constants_2.CommandArgDescription],
            preview: parsed[constants_2.CommandArgPreview],
            link_agent_label: parsed[constants_2.CommandArgLinkLabel],
            use_link_agent: !!parsed[constants_2.CommandArgLinkLabel],
            link_bypass_mabl_proxy: parsed[constants_2.CommandArgLinkBypass],
            source_control_tag_target: parsed[constants_1.CommandArgMablBranch],
            use_source_control_tag: !!parsed[constants_1.CommandArgMablBranch],
            variables: parsed[constants_2.CommandArgVariables],
        };
        environment = await apiClient.createEnvironment(environment);
        loggingProvider_1.logger.info(chalk_1.default.green(`Environment ${chalk_1.default.bold(environment.id ?? '')} CREATED`));
        const applicationId = parsed[constants_1.CommandArgApplicationId];
        if (applicationId) {
            loggingProvider_1.logger.info('Associating URLs with environment');
            const createDeploymentsPromises = (parsed[constants_2.CommandArgUrlApp] || [])
                .map((url) => (0, add_1.createDeploymentForUrl)(apiClient, environment, applicationId, url, mablApi_1.Deployment.DeploymentTypeEnum.WebApplication))
                .concat((parsed[constants_1.CommandArgUrlApi] || []).map((url) => (0, add_1.createDeploymentForUrl)(apiClient, environment, applicationId, url, mablApi_1.Deployment.DeploymentTypeEnum.Api)));
            await Promise.all(createDeploymentsPromises);
        }
    }
    catch (error) {
        throw new Error(`Error creating environment: ${error}`);
    }
    return environment.id;
}
