"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const core_1 = require("@oclif/core");
const heroku_cli_util_1 = require("@heroku/heroku-cli-util");
const color_1 = require("@heroku-cli/color");
const command_1 = require("@heroku-cli/command");
const inquirer = require("inquirer");
const path = require("path");
const os = require("os");
const fs = require("fs-extra");
function sshKeygen(file, quiet) {
    const spawn = require('child_process').spawn;
    return new Promise(function (resolve, reject) {
        spawn('ssh-keygen', ['-o', '-t', 'rsa', '-N', '', '-f', file], { stdio: quiet ? null : 'inherit' })
            .on('close', (code) => code === 0 ? resolve(null) : reject(code));
    });
}
async function confirmPrompt(message) {
    if (process.stdin.isTTY) {
        return inquirer.prompt([{
                type: 'confirm',
                name: 'yes',
                message: message,
            }]);
    }
    const data = await heroku_cli_util_1.hux.prompt(message + ' [Y/n]');
    return { yes: /^y(es)?/i.test(data) };
}
class Add extends command_1.Command {
    async run() {
        const { flags, args } = await this.parse(Add);
        const sshdir = path.join(os.homedir(), '.ssh');
        const generate = async function () {
            await fs.ensureDir(sshdir, { mode: 0o700 });
            await sshKeygen(path.join(sshdir, 'id_rsa'), flags.quiet);
        };
        const findKey = async function () {
            const defaultKeyPath = path.join(sshdir, 'id_rsa.pub');
            const defaultKeyExists = await fs.pathExists(defaultKeyPath);
            const keys = (await fs.readdir(sshdir))
                .map(k => path.join(sshdir, k))
                .filter(k => path.extname(k) === '.pub');
            if (!defaultKeyExists && keys.length === 0) {
                core_1.ux.warn('Could not find an existing SSH key at ' + path.join('~', '.ssh', 'id_rsa.pub'));
                if (!flags.yes) {
                    const resp = await confirmPrompt('Would you like to generate a new one?');
                    if (!resp.yes)
                        return;
                }
                await generate();
                return defaultKeyPath;
            }
            if (keys.length === 1) {
                const key = keys[0];
                core_1.ux.log(`Found an SSH public key at ${color_1.default.cyan(key)}`);
                if (!flags.yes) {
                    const resp = await confirmPrompt('Would you like to upload it to Heroku?');
                    if (!resp.yes)
                        return;
                }
                return key;
            }
            const resp = await inquirer.prompt([{
                    type: 'list',
                    name: 'key',
                    choices: keys,
                    message: 'Which SSH key would you like to upload?',
                }]);
            return resp.key;
        };
        let key = args.key;
        if (!key)
            key = await findKey();
        if (!key)
            throw new Error('No key to upload');
        core_1.ux.action.start(`Uploading ${color_1.default.cyan(key)} SSH key`);
        const publicKey = await fs.readFile(key, { encoding: 'utf8' });
        await this.heroku.post('/account/keys', {
            body: {
                public_key: publicKey,
            },
        });
        core_1.ux.action.stop();
    }
}
exports.default = Add;
Add.description = 'add an SSH key for a user';
Add.help = 'if no KEY is specified, will try to find ~/.ssh/id_rsa.pub';
Add.example = `$ heroku keys:add
Could not find an existing public key.
Would you like to generate one? [Yn] y
Generating new SSH public key.
Uploading SSH public key /.ssh/id_rsa.pub... done

$ heroku keys:add /my/key.pub
Uploading SSH public key /my/key.pub... done`;
Add.flags = {
    quiet: command_1.flags.boolean({ hidden: true }),
    yes: command_1.flags.boolean({ char: 'y', description: 'automatically answer yes for all prompts' }),
};
Add.args = {
    key: core_1.Args.string({ description: 'absolute path to the key located on disk. If omitted, we use the default rsa key.' }),
};
