"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 path = require("path");
const shelljs = require("shelljs");
class UpdateCommand {
    constructor($options, $projectData, $platformService, $platformsData, $pluginsService, $projectDataService, $fs, $logger) {
        this.$options = $options;
        this.$projectData = $projectData;
        this.$platformService = $platformService;
        this.$platformsData = $platformsData;
        this.$pluginsService = $pluginsService;
        this.$projectDataService = $projectDataService;
        this.$fs = $fs;
        this.$logger = $logger;
        this.allowedParameters = [];
        this.$projectData.initializeProjectData();
    }
    execute(args) {
        return __awaiter(this, void 0, void 0, function* () {
            let folders = ["lib", "hooks", "platforms", "node_modules"];
            let tmpDir = path.join(this.$projectData.projectDir, ".tmp_backup");
            try {
                shelljs.rm("-fr", tmpDir);
                shelljs.mkdir(tmpDir);
                shelljs.cp(path.join(this.$projectData.projectDir, "package.json"), tmpDir);
                for (let folder of folders) {
                    let folderToCopy = path.join(this.$projectData.projectDir, folder);
                    if (this.$fs.exists(folderToCopy)) {
                        shelljs.cp("-rf", folderToCopy, tmpDir);
                    }
                }
            }
            catch (error) {
                this.$logger.error("Could not backup project folders!");
                return;
            }
            try {
                yield this.executeCore(args, folders);
            }
            catch (error) {
                shelljs.cp("-f", path.join(tmpDir, "package.json"), this.$projectData.projectDir);
                for (let folder of folders) {
                    shelljs.rm("-rf", path.join(this.$projectData.projectDir, folder));
                    let folderToCopy = path.join(tmpDir, folder);
                    if (this.$fs.exists(folderToCopy)) {
                        shelljs.cp("-fr", folderToCopy, this.$projectData.projectDir);
                    }
                }
                this.$logger.error("Could not update the project!");
            }
            finally {
                shelljs.rm("-fr", tmpDir);
            }
        });
    }
    canExecute(args) {
        return __awaiter(this, void 0, void 0, function* () {
            return args.length < 2 && this.$projectData.projectDir !== "";
        });
    }
    executeCore(args, folders) {
        return __awaiter(this, void 0, void 0, function* () {
            let platforms = this.$platformService.getInstalledPlatforms(this.$projectData);
            let availablePlatforms = this.$platformService.getAvailablePlatforms(this.$projectData);
            let packagePlatforms = [];
            for (let platform of availablePlatforms) {
                let platformData = this.$platformsData.getPlatformData(platform, this.$projectData);
                const platformVersion = this.$projectDataService.getNSValue(this.$projectData.projectDir, platformData.frameworkPackageName);
                if (platformVersion) {
                    packagePlatforms.push(platform);
                    this.$projectDataService.removeNSProperty(this.$projectData.projectDir, platformData.frameworkPackageName);
                }
            }
            yield this.$platformService.removePlatforms(platforms, this.$projectData);
            yield this.$pluginsService.remove("tns-core-modules", this.$projectData);
            yield this.$pluginsService.remove("tns-core-modules-widgets", this.$projectData);
            for (let folder of folders) {
                shelljs.rm("-fr", folder);
            }
            platforms = platforms.concat(packagePlatforms);
            if (args.length === 1) {
                for (let platform of platforms) {
                    yield this.$platformService.addPlatforms([platform + "@" + args[0]], this.$options.platformTemplate, this.$projectData, this.$options, this.$options.frameworkPath);
                }
                yield this.$pluginsService.add("tns-core-modules@" + args[0], this.$projectData);
            }
            else {
                yield this.$platformService.addPlatforms(platforms, this.$options.platformTemplate, this.$projectData, this.$options, this.$options.frameworkPath);
                yield this.$pluginsService.add("tns-core-modules", this.$projectData);
            }
            yield this.$pluginsService.ensureAllDependenciesAreInstalled(this.$projectData);
        });
    }
}
exports.UpdateCommand = UpdateCommand;
$injector.registerCommand("update", UpdateCommand);
