"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const fs_1 = tslib_1.__importDefault(require("fs"));
const path_1 = tslib_1.__importDefault(require("path"));
const os_1 = tslib_1.__importDefault(require("os"));
const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
const models_cloud_1 = tslib_1.__importDefault(require("@tradle/models-cloud"));
const errors_1 = require("./errors");
const logger_1 = require("./logger");
const utils_1 = require("./utils");
const regions = models_cloud_1.default['tradle.cloud.AWSRegion'].enum.map(({ id, title }) => ({
    name: title,
    value: id.replace(/[.]/g, '-')
}));
const PROFILE_REGEX = /^\[(?:[^\s]*?\s)?(.*)\]$/;
const getProfileName = line => line.match(PROFILE_REGEX)[1];
const parseConf = conf => ({
    profiles: conf.split('\n')
        .filter(s => s.startsWith('['))
        .map(getProfileName)
});
const isVirginConfiguration = () => {
    const confDir = path_1.default.resolve(process.cwd(), 'conf');
    if (!fs_1.default.existsSync(confDir))
        return true;
    const local = fs_1.default.readdirSync(confDir);
    return !local.length;
};
const getProfiles = () => {
    let conf;
    try {
        conf = fs_1.default.readFileSync(`${os_1.default.homedir()}/.aws/credentials`, { encoding: 'utf8' });
    }
    catch (err) {
        return ['default'];
    }
    const { profiles } = parseConf(conf);
    return profiles.includes('default') ? profiles : ['default'].concat(profiles);
};
exports.init = (conf) => tslib_1.__awaiter(this, void 0, void 0, function* () {
    if (fs_1.default.existsSync('./.env')) {
        yield exports.confirmOrAbort('This will overwrite your .env file');
    }
    const haveRemote = yield exports.confirm('Have you already deployed your MyCloud to AWS?');
    const getLocal = [
        {
            type: 'confirm',
            name: 'haveLocal',
            message: 'Do you have a local development environment? (a clone of https://github.com/tradle/serverless)',
        },
        {
            type: 'input',
            name: 'projectPath',
            message: 'Enter the path to your local development environment (a clone of https://github.com/tradle/serverless)',
            when: answers => conf.local || answers.haveLocal,
            validate: local => {
                if (!utils_1.isValidProjectPath(local)) {
                    return 'Provided path doesn\'t contain a serverless.yml, please try again';
                }
                return true;
            }
        }
    ];
    if (!haveRemote) {
        return Object.assign({ haveRemote }, (yield inquirer_1.default.prompt(getLocal)));
    }
    const getRemoteAndLocal = [
        {
            type: 'list',
            name: 'region',
            message: 'Which AWS region is your deployment in?',
            choices: regions
        },
        {
            type: 'list',
            name: 'awsProfile',
            message: 'Select your aws profile',
            choices: getProfiles()
                .map(profile => ({
                name: profile,
                value: profile
            }))
                .concat([
                new inquirer_1.default.Separator(),
                {
                    name: 'Other (specify)',
                    value: null
                }
            ]),
        },
        {
            type: 'input',
            name: 'awsProfile',
            message: 'profile',
            when: answers => answers.overwriteEnv && !answers.awsProfile
        },
        {
            type: 'list',
            name: 'stack',
            message: 'Which Tradle stack will you be configuring?',
            choices: ({ region, awsProfile }) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                const stackInfos = yield conf.getStacks({
                    profile: awsProfile,
                    region
                });
                if (!stackInfos.length) {
                    throw new Error('no stacks found');
                }
                return stackInfos
                    .filter(({ name }) => utils_1.isMyCloudStackName(name))
                    .map(({ name, id }) => ({
                    name,
                    value: { name, id }
                }));
            })
        },
    ]
        .concat(getLocal)
        .concat({
        type: 'confirm',
        name: 'loadCurrentConf',
        message: 'Would you like to pull your current configuration?',
        when: isVirginConfiguration,
    });
    return Object.assign({ haveRemote }, (yield inquirer_1.default.prompt(getRemoteAndLocal)));
});
exports.fn = (conf, message) => {
    return inquirer_1.default.prompt([
        {
            type: 'list',
            name: 'fn',
            message,
            choices: conf.getFunctionShortNames
        }
    ])
        .then(({ fn }) => fn);
};
exports.confirm = (message, defaultValue = true) => {
    return inquirer_1.default.prompt([
        {
            type: 'confirm',
            name: 'confirm',
            message,
            default: defaultValue,
        }
    ])
        .then(({ confirm }) => confirm);
};
exports.confirmOrAbort = (msg, defaultValue) => tslib_1.__awaiter(this, void 0, void 0, function* () {
    const confirmed = yield exports.confirm(msg, defaultValue);
    if (!confirmed) {
        throw new errors_1.Errors.UserAborted();
    }
});
exports.ask = (message, validate) => {
    return inquirer_1.default.prompt([
        {
            type: 'input',
            name: 'answer',
            message,
            validate,
        }
    ])
        .then(({ answer }) => answer);
};
exports.chooseEC2KeyPair = (ec2) => tslib_1.__awaiter(this, void 0, void 0, function* () {
    const { region } = ec2.config;
    const know = yield exports.confirm('Do you know the name of the EC2 key pair you want to use?');
    if (know) {
        const key = yield exports.ask('What is the name of the EC2 key pair you configured in AWS?');
        const exists = yield utils_1.doKeyPairsExist(ec2, [key]);
        if (exists)
            return key;
        logger_1.logger.warn(`Key pair not found in region ${region}`);
        return exports.chooseEC2KeyPair(ec2);
    }
    const keyPairs = yield utils_1.listKeyPairs(ec2);
    if (!keyPairs.length) {
        throw new errors_1.Errors.InvalidInput(`No key pairs found in region: ${region}`);
    }
    return exports.choose({
        message: 'Choose the key pair to set up for SSH access',
        choices: keyPairs,
    });
});
exports.choose = ({ message, choices, defaultValue }) => tslib_1.__awaiter(this, void 0, void 0, function* () {
    return inquirer_1.default.prompt([
        {
            type: 'list',
            name: 'choice',
            message,
            choices: typeof choices === 'function' ? choices : () => choices,
            default: defaultValue,
        }
    ])
        .then(({ choice }) => choice);
});
exports.chooseRegion = (opts) => tslib_1.__awaiter(this, void 0, void 0, function* () {
    const message = opts && opts.message || 'Choose a deployment region';
    return exports.choose({
        message,
        choices: regions,
        defaultValue: opts && opts.default,
    });
});
exports.chooseMultiple = ({ min, max, choices, message }) => tslib_1.__awaiter(this, void 0, void 0, function* () {
    return inquirer_1.default.prompt([
        {
            type: 'checkbox',
            choices,
            name: 'answer',
            message,
            validate: (choices) => {
                if (choices.length < min || choices.length > max) {
                    throw new Error(message);
                }
                return true;
            }
        }
    ])
        .then(({ answer }) => answer);
});
exports.chooseAZs = (client, { region, count }) => tslib_1.__awaiter(this, void 0, void 0, function* () {
    const azs = yield utils_1.listAZs({ region });
    if (azs.length === count)
        return azs;
    return exports.chooseMultiple({
        min: count,
        max: count,
        message: `Choose ${count} availability zones`,
        choices: azs.map(name => ({ name, value: name })),
    });
});
//# sourceMappingURL=prompts.js.map