"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const core_1 = require("@oclif/core");
const template_1 = require("../create/template");
const templateProcessor_1 = require("../create/templateProcessor");
const fs = (0, tslib_1.__importStar)(require("fs-extra"));
const inquirer_1 = (0, tslib_1.__importDefault)(require("inquirer"));
class Create extends core_1.Command {
    constructor() {
        super(...arguments);
        this.dir = ".";
    }
    async catch(error) {
        // do something or
        // re-throw to be handled globally
        throw error;
    }
    async run() {
        const { flags, args } = await this.parse(Create);
        this.dir = args.directory.indexOf("/") !== 0 ? process.cwd() + "/" + args.directory : args.directory;
        if (fs.existsSync(this.dir)) {
            let numFiles = fs.readdirSync(this.dir).length;
            if (numFiles && fs.existsSync(this.dir + "/tstemplate.json")) {
                await this.handleExistingProject();
                return;
            }
        }
        else {
            let proceed = await core_1.CliUx.ux.confirm("Create new workspace at " + this.dir + "?");
            if (!proceed) {
                return;
            }
            fs.mkdirSync(this.dir, { recursive: true });
        }
        let template = flags.template;
        if (!template)
            template = await this.showTemplateSelection();
        let templateDef = template_1.Templates.getTemplateDescriptor(template);
        let values = await this.collectFieldValues(templateDef.templateFields);
        template_1.Templates.copyTemplate(template, this.dir);
        await this.processTemplateUpdate(templateDef, values);
    }
    async processTemplateUpdate(templateDef, values) {
        let templateProcessor = new templateProcessor_1.TemplateProcessor(templateDef, this.dir);
        await templateProcessor.processTemplateUpdate(values);
        console.log("Project successfully initialized!\r\n");
    }
    async handleExistingProject() {
        let templateDef = fs.readJsonSync(this.dir + "/tstemplate.json");
        if (!templateDef)
            throw new Error("Template file is invalid or not readable");
        let proceed = await core_1.CliUx.ux.confirm("Existing workspace detected, would you like to try and update template values?\r\nThis may not work correctly, please save your current workspace before continuing");
        if (!proceed)
            return;
        let values = await this.collectFieldValues(templateDef.templateFields);
        await this.processTemplateUpdate(templateDef, values);
    }
    async showTemplateSelection() {
        let template;
        while (!template) {
            let responses = await inquirer_1.default.prompt([{
                    name: 'template',
                    message: 'Select project template',
                    type: 'list',
                    choices: template_1.Templates.templatesList.map((template) => {
                        return { name: template.name + ": " + template.description, value: template.id };
                    }),
                }]);
            template = responses.template;
            if (!template)
                console.log("\r\nInvalid selection!\r\n");
        }
        return template;
    }
    async collectFieldValues(templateDef) {
        let responses = await inquirer_1.default.prompt(templateDef.map((fieldDef) => {
            return {
                name: fieldDef.name,
                message: fieldDef.prompt + ":",
                type: "input",
                validate: (val) => {
                    return val != "";
                }
            };
        }));
        let values = [];
        for (let i = 0; i < templateDef.length; i++) {
            let value = responses[templateDef[i].name];
            if (value == undefined)
                throw new Error("Value not provided");
            values.push(responses[templateDef[i].name]);
        }
        return values;
    }
}
exports.default = Create;
Create.description = 'Create a new TokenScript project';
Create.flags = {
    // can pass either --force or -f
    template: core_1.Flags.string({ char: "t", options: template_1.Templates.templatesList.map((template) => template.id) }),
};
Create.args = [
    { name: 'directory', default: process.cwd() }
];
