"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());
    });
};
const helpers = require("./../common/helpers");
class PluginVariablesService {
    constructor($errors, $pluginVariablesHelper, $projectData, $projectDataService, $prompter, $fs) {
        this.$errors = $errors;
        this.$pluginVariablesHelper = $pluginVariablesHelper;
        this.$projectData = $projectData;
        this.$projectDataService = $projectDataService;
        this.$prompter = $prompter;
        this.$fs = $fs;
    }
    getPluginVariablePropertyName(pluginName) {
        return `${pluginName}-${PluginVariablesService.PLUGIN_VARIABLES_KEY}`;
    }
    savePluginVariablesInProjectFile(pluginData) {
        return __awaiter(this, void 0, void 0, function* () {
            let values = Object.create(null);
            yield this.executeForAllPluginVariables(pluginData, (pluginVariableData) => __awaiter(this, void 0, void 0, function* () {
                let pluginVariableValue = yield this.getPluginVariableValue(pluginVariableData);
                this.ensurePluginVariableValue(pluginVariableValue, `Unable to find value for ${pluginVariableData.name} plugin variable from ${pluginData.name} plugin. Ensure the --var option is specified or the plugin variable has default value.`);
                values[pluginVariableData.name] = pluginVariableValue;
            }));
            if (!_.isEmpty(values)) {
                this.$projectDataService.initialize(this.$projectData.projectDir);
                this.$projectDataService.setValue(this.getPluginVariablePropertyName(pluginData.name), values);
            }
        });
    }
    removePluginVariablesFromProjectFile(pluginName) {
        this.$projectDataService.initialize(this.$projectData.projectDir);
        this.$projectDataService.removeProperty(this.getPluginVariablePropertyName(pluginName));
    }
    interpolatePluginVariables(pluginData, pluginConfigurationFilePath) {
        return __awaiter(this, void 0, void 0, function* () {
            let pluginConfigurationFileContent = this.$fs.readText(pluginConfigurationFilePath);
            yield this.executeForAllPluginVariables(pluginData, (pluginVariableData) => __awaiter(this, void 0, void 0, function* () {
                this.ensurePluginVariableValue(pluginVariableData.value, `Unable to find the value for ${pluginVariableData.name} plugin variable into project package.json file. Verify that your package.json file is correct and try again.`);
                pluginConfigurationFileContent = this.interpolateCore(pluginVariableData.name, pluginVariableData.value, pluginConfigurationFileContent);
            }));
            this.$fs.writeFile(pluginConfigurationFilePath, pluginConfigurationFileContent);
        });
    }
    interpolateAppIdentifier(pluginConfigurationFilePath) {
        let pluginConfigurationFileContent = this.$fs.readText(pluginConfigurationFilePath);
        let newContent = this.interpolateCore("nativescript.id", this.$projectData.projectId, pluginConfigurationFileContent);
        this.$fs.writeFile(pluginConfigurationFilePath, newContent);
    }
    interpolate(pluginData, pluginConfigurationFilePath) {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.interpolatePluginVariables(pluginData, pluginConfigurationFilePath);
            this.interpolateAppIdentifier(pluginConfigurationFilePath);
        });
    }
    interpolateCore(name, value, content) {
        return content.replace(new RegExp(`{${name}}`, "gi"), value);
    }
    ensurePluginVariableValue(pluginVariableValue, errorMessage) {
        if (!pluginVariableValue) {
            this.$errors.failWithoutHelp(errorMessage);
        }
    }
    getPluginVariableValue(pluginVariableData) {
        return __awaiter(this, void 0, void 0, function* () {
            let pluginVariableName = pluginVariableData.name;
            let value = this.$pluginVariablesHelper.getPluginVariableFromVarOption(pluginVariableName);
            if (value) {
                value = value[pluginVariableName];
            }
            else {
                value = pluginVariableData.defaultValue;
                if (!value && helpers.isInteractive()) {
                    let promptSchema = {
                        name: pluginVariableName,
                        type: "input",
                        message: `Enter value for ${pluginVariableName} variable:`,
                        validate: (val) => !!val ? true : 'Please enter a value!'
                    };
                    let promptData = yield this.$prompter.get([promptSchema]);
                    value = promptData[pluginVariableName];
                }
            }
            return value;
        });
    }
    executeForAllPluginVariables(pluginData, action) {
        return __awaiter(this, void 0, void 0, function* () {
            let pluginVariables = pluginData.pluginVariables;
            let pluginVariablesNames = _.keys(pluginVariables);
            yield Promise.all(_.map(pluginVariablesNames, pluginVariableName => action(this.createPluginVariableData(pluginData, pluginVariableName))));
        });
    }
    createPluginVariableData(pluginData, pluginVariableName) {
        let variableData = pluginData.pluginVariables[pluginVariableName];
        variableData.name = pluginVariableName;
        this.$projectDataService.initialize(this.$projectData.projectDir);
        let pluginVariableValues = this.$projectDataService.getValue(this.getPluginVariablePropertyName(pluginData.name));
        variableData.value = pluginVariableValues ? pluginVariableValues[pluginVariableName] : undefined;
        return variableData;
    }
}
PluginVariablesService.PLUGIN_VARIABLES_KEY = "variables";
exports.PluginVariablesService = PluginVariablesService;
$injector.register("pluginVariablesService", PluginVariablesService);
