"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 helpers_1 = require("../common/helpers");
const os_1 = require("os");
class PlatformEnvironmentRequirements {
    constructor($commandsService, $doctorService, $errors, $nativescriptCloudExtensionService, $logger, $prompter, $staticConfig) {
        this.$commandsService = $commandsService;
        this.$doctorService = $doctorService;
        this.$errors = $errors;
        this.$nativescriptCloudExtensionService = $nativescriptCloudExtensionService;
        this.$logger = $logger;
        this.$prompter = $prompter;
        this.$staticConfig = $staticConfig;
        this.cliCommandToCloudCommandName = {
            "build": "tns cloud build",
            "run": "tns cloud run",
            "deploy": "tns cloud deploy"
        };
    }
    checkEnvironmentRequirements(platform) {
        return __awaiter(this, void 0, void 0, function* () {
            if (process.env.NS_SKIP_ENV_CHECK) {
                return true;
            }
            const canExecute = yield this.$doctorService.canExecuteLocalBuild(platform);
            if (!canExecute) {
                if (!helpers_1.isInteractive()) {
                    this.fail(`You are missing the ${constants.NATIVESCRIPT_CLOUD_EXTENSION_NAME} extension and you will not be able to execute cloud builds. Your environment is not configured properly and you will not be able to execute local builds. To continue, choose one of the following options: ` + os_1.EOL
                        + "Run $ tns setup command to run the setup script to try to automatically configure your environment for local builds." + os_1.EOL
                        + `Run $ tns cloud setup command to install the ${constants.NATIVESCRIPT_CLOUD_EXTENSION_NAME} extension to configure your environment for cloud builds.` + os_1.EOL
                        + `Verify that your environment is configured according to the system requirements described at ${this.$staticConfig.SYS_REQUIREMENTS_LINK}`);
                }
                this.$logger.info(`You are missing the ${constants.NATIVESCRIPT_CLOUD_EXTENSION_NAME} extension and you will not be able to execute cloud builds. Your environment is not configured properly and you will not be able to execute local builds. ` + os_1.EOL
                    + `Select "Configure for Cloud Builds" to install the ${constants.NATIVESCRIPT_CLOUD_EXTENSION_NAME} extension and automatically configure your environment for cloud builds.` + os_1.EOL
                    + `Select "Configure for Local Builds" to run the setup script and automatically configure your environment for local builds.`
                    + `Select "Configure for Both Local and Cloud Builds" to automatically configure your environment for both options.`
                    + `Select "Skip Step and Configure Manually" to disregard these options and install any required components manually.`);
                const selectedOption = yield this.$prompter.promptForChoice(PlatformEnvironmentRequirements.NOT_CONFIGURED_ENV_MESSAGE, [
                    PlatformEnvironmentRequirements.CLOUD_BUILDS_OPTION_NAME,
                    PlatformEnvironmentRequirements.SETUP_SCRIPT_OPTION_NAME,
                    PlatformEnvironmentRequirements.BOTH_CLOUD_BUILDS_AND_SETUP_SCRIPT_OPTION_NAME,
                    PlatformEnvironmentRequirements.MANUALLY_SETUP_OPTION_NAME,
                ]);
                yield this.processCloudBuildsIfNeeded(platform, selectedOption);
                this.processManuallySetupIfNeeded(platform, selectedOption);
                if (selectedOption === PlatformEnvironmentRequirements.SETUP_SCRIPT_OPTION_NAME) {
                    yield this.$doctorService.runSetupScript();
                    if (yield this.$doctorService.canExecuteLocalBuild(platform)) {
                        return true;
                    }
                    const option = yield this.$prompter.promptForChoice(PlatformEnvironmentRequirements.NOT_CONFIGURED_ENV_AFTER_SETUP_SCRIPT_MESSAGE, [
                        PlatformEnvironmentRequirements.CLOUD_BUILDS_OPTION_NAME,
                        PlatformEnvironmentRequirements.MANUALLY_SETUP_OPTION_NAME
                    ]);
                    yield this.processCloudBuildsIfNeeded(platform, option);
                    this.processManuallySetupIfNeeded(platform, option);
                }
                if (selectedOption === PlatformEnvironmentRequirements.BOTH_CLOUD_BUILDS_AND_SETUP_SCRIPT_OPTION_NAME) {
                    yield this.processBothCloudBuildsAndSetupScript(platform);
                    if (yield this.$doctorService.canExecuteLocalBuild(platform)) {
                        return true;
                    }
                    this.processManuallySetup(platform);
                }
            }
            return true;
        });
    }
    processCloudBuildsIfNeeded(platform, selectedOption) {
        return __awaiter(this, void 0, void 0, function* () {
            if (selectedOption === PlatformEnvironmentRequirements.CLOUD_BUILDS_OPTION_NAME) {
                yield this.processCloudBuilds(platform);
            }
        });
    }
    processCloudBuilds(platform) {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.processCloudBuildsCore(platform);
            this.fail(this.getCloudBuildsMessage(platform));
        });
    }
    processCloudBuildsCore(platform) {
        return this.$nativescriptCloudExtensionService.install();
    }
    getCloudBuildsMessage(platform) {
        const cloudCommandName = this.cliCommandToCloudCommandName[this.$commandsService.currentCommandData.commandName];
        if (!cloudCommandName) {
            return `In order to test your application use the $ tns login command to log in with your account and then $ tns cloud build command to build your app in the cloud.`;
        }
        if (!platform) {
            return `Use the $ tns login command to log in with your account and then $ ${cloudCommandName.toLowerCase()} command.`;
        }
        return `Use the $ tns login command to log in with your account and then $ ${cloudCommandName.toLowerCase()} ${platform.toLowerCase()} command.`;
    }
    processManuallySetupIfNeeded(platform, selectedOption) {
        if (selectedOption === PlatformEnvironmentRequirements.MANUALLY_SETUP_OPTION_NAME) {
            this.processManuallySetup(platform);
        }
    }
    processManuallySetup(platform) {
        this.fail(`To be able to build for ${platform}, verify that your environment is configured according to the system requirements described at ${this.$staticConfig.SYS_REQUIREMENTS_LINK}`);
    }
    processBothCloudBuildsAndSetupScript(platform) {
        return __awaiter(this, void 0, void 0, function* () {
            try {
                yield this.processCloudBuildsCore(platform);
            }
            catch (e) {
                this.$logger.trace(`Error while installing ${constants.NATIVESCRIPT_CLOUD_EXTENSION_NAME} extension. ${e.message}.`);
            }
            yield this.$doctorService.runSetupScript();
        });
    }
    fail(message) {
        this.$errors.fail({ formatStr: message, suppressCommandHelp: true, printOnStdout: true });
    }
}
PlatformEnvironmentRequirements.CLOUD_BUILDS_OPTION_NAME = "Configure for Cloud Builds";
PlatformEnvironmentRequirements.SETUP_SCRIPT_OPTION_NAME = "Configure for Local Builds";
PlatformEnvironmentRequirements.MANUALLY_SETUP_OPTION_NAME = "Skip Step and Configure Manually";
PlatformEnvironmentRequirements.BOTH_CLOUD_BUILDS_AND_SETUP_SCRIPT_OPTION_NAME = "Configure for Both Local and Cloud Builds";
PlatformEnvironmentRequirements.NOT_CONFIGURED_ENV_MESSAGE = "To continue, choose one of the following options: ";
PlatformEnvironmentRequirements.NOT_CONFIGURED_ENV_AFTER_SETUP_SCRIPT_MESSAGE = "The setup script was not able to configure your environment for local builds. To execute local builds, you have to set up your environment manually. To continue, choose one of the following options:";
exports.PlatformEnvironmentRequirements = PlatformEnvironmentRequirements;
$injector.register("platformEnvironmentRequirements", PlatformEnvironmentRequirements);
