"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const constants = require("../constants");
const path = require("path");
const helpers_1 = require("../common/helpers");
class CreateProjectCommand {
    constructor($projectService, $logger, $errors, $options, $prompter, $stringParameter) {
        this.$projectService = $projectService;
        this.$logger = $logger;
        this.$errors = $errors;
        this.$options = $options;
        this.$prompter = $prompter;
        this.$stringParameter = $stringParameter;
        this.enableHooks = false;
        this.allowedParameters = [this.$stringParameter];
        this.isInteractionIntroShown = false;
    }
    execute(args) {
        return __awaiter(this, void 0, void 0, function* () {
            const interactiveAdverbs = ["First", "Next", "Finally"];
            const getNextInteractiveAdverb = () => {
                return interactiveAdverbs.shift() || "Next";
            };
            if ((this.$options.tsc || this.$options.ng || this.$options.vue || this.$options.js) && this.$options.template) {
                this.$errors.fail("You cannot use a flavor option like --ng, --vue, --tsc and --js together with --template.");
            }
            let projectName = args[0];
            let selectedTemplate;
            if (this.$options.js) {
                selectedTemplate = constants.JAVASCRIPT_NAME;
            }
            else if (this.$options.tsc) {
                selectedTemplate = constants.TYPESCRIPT_NAME;
            }
            else if (this.$options.ng) {
                selectedTemplate = constants.ANGULAR_NAME;
            }
            else if (this.$options.vue) {
                selectedTemplate = constants.VUE_NAME;
            }
            else {
                selectedTemplate = this.$options.template;
            }
            if (!projectName && helpers_1.isInteractive()) {
                this.printInteractiveCreationIntroIfNeeded();
                projectName = yield this.$prompter.getString(`${getNextInteractiveAdverb()}, what will be the name of your app?`, { allowEmpty: false });
                this.$logger.info();
            }
            projectName = yield this.$projectService.validateProjectName({ projectName: projectName, force: this.$options.force, pathToProject: this.$options.path });
            if (!selectedTemplate && helpers_1.isInteractive()) {
                this.printInteractiveCreationIntroIfNeeded();
                selectedTemplate = yield this.interactiveFlavorAndTemplateSelection(getNextInteractiveAdverb(), getNextInteractiveAdverb());
            }
            this.createdProjectData = yield this.$projectService.createProject({
                projectName: projectName,
                template: selectedTemplate,
                appId: this.$options.appid,
                pathToProject: this.$options.path,
                force: true,
                ignoreScripts: this.$options.ignoreScripts
            });
        });
    }
    interactiveFlavorAndTemplateSelection(flavorAdverb, templateAdverb) {
        return __awaiter(this, void 0, void 0, function* () {
            const selectedFlavor = yield this.interactiveFlavorSelection(flavorAdverb);
            const selectedTemplate = yield this.interactiveTemplateSelection(selectedFlavor, templateAdverb);
            return selectedTemplate;
        });
    }
    interactiveFlavorSelection(adverb) {
        return __awaiter(this, void 0, void 0, function* () {
            const flavorSelection = yield this.$prompter.promptForDetailedChoice(`${adverb}, which style of NativeScript project would you like to use:`, [
                { key: constants.NgFlavorName, description: "Learn more at https://nativescript.org/angular" },
                { key: constants.VueFlavorName, description: "Learn more at https://nativescript.org/vue" },
                { key: constants.TsFlavorName, description: "Learn more at https://nativescript.org/typescript" },
                { key: constants.JsFlavorName, description: "Use NativeScript without any framework" },
            ]);
            return flavorSelection;
        });
    }
    printInteractiveCreationIntroIfNeeded() {
        if (!this.isInteractionIntroShown) {
            this.isInteractionIntroShown = true;
            this.$logger.info();
            this.$logger.printMarkdown(`# Let’s create a NativeScript app!`);
            this.$logger.printMarkdown(`
Answer the following questions to help us build the right app for you. (Note: you
can skip this prompt next time using the --template option, or the --ng, --vue, --ts,
or --js flags.)
`);
        }
    }
    interactiveTemplateSelection(flavorSelection, adverb) {
        return __awaiter(this, void 0, void 0, function* () {
            const selectedFlavorTemplates = [];
            let selectedTemplate;
            switch (flavorSelection) {
                case constants.NgFlavorName: {
                    selectedFlavorTemplates.push(...this.getNgTemplates());
                    break;
                }
                case constants.VueFlavorName: {
                    selectedFlavorTemplates.push(...this.getVueTemplates());
                    break;
                }
                case constants.TsFlavorName: {
                    selectedFlavorTemplates.push(...this.getTsTemplates());
                    break;
                }
                case constants.JsFlavorName: {
                    selectedFlavorTemplates.push(...this.getJsTemplates());
                    break;
                }
            }
            if (selectedFlavorTemplates.length > 1) {
                this.$logger.info();
                const templateChoices = selectedFlavorTemplates.map((template) => {
                    return { key: template.key, description: template.description };
                });
                const selectedTemplateKey = yield this.$prompter.promptForDetailedChoice(`${adverb}, which template would you like to start from:`, templateChoices);
                selectedTemplate = selectedFlavorTemplates.find(t => t.key === selectedTemplateKey).value;
            }
            else {
                selectedTemplate = selectedFlavorTemplates[0].value;
            }
            return selectedTemplate;
        });
    }
    getJsTemplates() {
        const templates = [{
                key: CreateProjectCommand.HelloWorldTemplateKey,
                value: constants.RESERVED_TEMPLATE_NAMES.javascript,
                description: CreateProjectCommand.HelloWorldTemplateDescription
            },
            {
                key: CreateProjectCommand.DrawerTemplateKey,
                value: "tns-template-drawer-navigation",
                description: CreateProjectCommand.DrawerTemplateDescription
            },
            {
                key: CreateProjectCommand.TabsTemplateKey,
                value: "tns-template-tab-navigation",
                description: CreateProjectCommand.TabsTemplateDescription
            }];
        return templates;
    }
    getTsTemplates() {
        const templates = [{
                key: CreateProjectCommand.HelloWorldTemplateKey,
                value: constants.RESERVED_TEMPLATE_NAMES.typescript,
                description: CreateProjectCommand.HelloWorldTemplateDescription
            },
            {
                key: CreateProjectCommand.DrawerTemplateKey,
                value: "tns-template-drawer-navigation-ts",
                description: CreateProjectCommand.DrawerTemplateDescription
            },
            {
                key: CreateProjectCommand.TabsTemplateKey,
                value: "tns-template-tab-navigation-ts",
                description: CreateProjectCommand.TabsTemplateDescription
            }];
        return templates;
    }
    getNgTemplates() {
        const templates = [{
                key: CreateProjectCommand.HelloWorldTemplateKey,
                value: constants.RESERVED_TEMPLATE_NAMES.angular,
                description: CreateProjectCommand.HelloWorldTemplateDescription
            },
            {
                key: CreateProjectCommand.DrawerTemplateKey,
                value: "tns-template-drawer-navigation-ng",
                description: CreateProjectCommand.DrawerTemplateDescription
            },
            {
                key: CreateProjectCommand.TabsTemplateKey,
                value: "tns-template-tab-navigation-ng",
                description: CreateProjectCommand.TabsTemplateDescription
            }];
        return templates;
    }
    getVueTemplates() {
        const templates = [{
                key: CreateProjectCommand.BlankTemplateKey,
                value: "tns-template-blank-vue",
                description: CreateProjectCommand.BlankTemplateDescription
            },
            {
                key: CreateProjectCommand.DrawerTemplateKey,
                value: "tns-template-drawer-navigation-vue",
                description: CreateProjectCommand.DrawerTemplateDescription
            }];
        return templates;
    }
    postCommandAction(args) {
        return __awaiter(this, void 0, void 0, function* () {
            const { projectDir } = this.createdProjectData;
            const relativePath = path.relative(process.cwd(), projectDir);
            this.$logger.printMarkdown(`Now you can navigate to your project with \`$ cd ${relativePath}\``);
            this.$logger.printMarkdown(`After that you can preview it on device by executing \`$ tns preview\``);
        });
    }
}
CreateProjectCommand.BlankTemplateKey = "Blank";
CreateProjectCommand.BlankTemplateDescription = "A blank app";
CreateProjectCommand.HelloWorldTemplateKey = "Hello World";
CreateProjectCommand.HelloWorldTemplateDescription = "A Hello World app";
CreateProjectCommand.DrawerTemplateKey = "SideDrawer";
CreateProjectCommand.DrawerTemplateDescription = "An app with pre-built pages that uses a drawer for navigation";
CreateProjectCommand.TabsTemplateKey = "Tabs";
CreateProjectCommand.TabsTemplateDescription = "An app with pre-built pages that uses tabs for navigation";
exports.CreateProjectCommand = CreateProjectCommand;
$injector.registerCommand("create", CreateProjectCommand);
