"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
const path = require("path");
const shell = require("shelljs");
const constants = require("../constants");
const helpers = require("../common/helpers");
const semver = require("semver");
const app_files_updater_1 = require("./app-files-updater");
const temp = require("temp");
const project_changes_info_1 = require("./project-changes-info");
const Future = require("fibers/future");
temp.track();
let clui = require("clui");
const buildInfoFileName = ".nsbuildinfo";
class PlatformService {
    constructor($devicesService, $errors, $fs, $logger, $npmInstallationManager, $platformsData, $projectData, $projectDataService, $prompter, $hooksService, $commandsService, $options, $nodeModulesBuilder, $pluginsService, $projectFilesManager, $mobileHelper, $hostInfo, $xmlValidator, $npm, $sysInfo, $staticConfig, $devicePlatformsConstants, $childProcess) {
        this.$devicesService = $devicesService;
        this.$errors = $errors;
        this.$fs = $fs;
        this.$logger = $logger;
        this.$npmInstallationManager = $npmInstallationManager;
        this.$platformsData = $platformsData;
        this.$projectData = $projectData;
        this.$projectDataService = $projectDataService;
        this.$prompter = $prompter;
        this.$hooksService = $hooksService;
        this.$commandsService = $commandsService;
        this.$options = $options;
        this.$nodeModulesBuilder = $nodeModulesBuilder;
        this.$pluginsService = $pluginsService;
        this.$projectFilesManager = $projectFilesManager;
        this.$mobileHelper = $mobileHelper;
        this.$hostInfo = $hostInfo;
        this.$xmlValidator = $xmlValidator;
        this.$npm = $npm;
        this.$sysInfo = $sysInfo;
        this.$staticConfig = $staticConfig;
        this.$devicePlatformsConstants = $devicePlatformsConstants;
        this.$childProcess = $childProcess;
    }
    addPlatforms(platforms) {
        return (() => {
            let platformsDir = this.$projectData.platformsDir;
            this.$fs.ensureDirectoryExists(platformsDir);
            _.each(platforms, platform => {
                this.addPlatform(platform.toLowerCase()).wait();
            });
        }).future()();
    }
    addPlatform(platformParam) {
        return (() => {
            let data = platformParam.split("@"), platform = data[0].toLowerCase(), version = data[1];
            this.validatePlatform(platform);
            let platformPath = path.join(this.$projectData.platformsDir, platform);
            if (this.$fs.exists(platformPath)) {
                this.$errors.failWithoutHelp("Platform %s already added", platform);
            }
            let platformData = this.$platformsData.getPlatformData(platform);
            let platformProjectService = platformData.platformProjectService;
            platformProjectService.validate().wait();
            this.$logger.trace("Creating NativeScript project for the %s platform", platform);
            this.$logger.trace("Path: %s", platformData.projectRoot);
            this.$logger.trace("Package: %s", this.$projectData.projectId);
            this.$logger.trace("Name: %s", this.$projectData.projectName);
            this.$logger.out("Copying template files...");
            let packageToInstall = "";
            let npmOptions = {
                pathToSave: path.join(this.$projectData.platformsDir, platform),
                dependencyType: "save"
            };
            if (!this.$options.frameworkPath) {
                packageToInstall = platformData.frameworkPackageName;
                npmOptions["version"] = version;
            }
            let spinner = new clui.Spinner("Installing " + packageToInstall);
            try {
                spinner.start();
                let downloadedPackagePath = this.$npmInstallationManager.install(packageToInstall, this.$projectData.projectDir, npmOptions).wait();
                let frameworkDir = path.join(downloadedPackagePath, constants.PROJECT_FRAMEWORK_FOLDER_NAME);
                frameworkDir = path.resolve(frameworkDir);
                let coreModuleName = this.addPlatformCore(platformData, frameworkDir).wait();
                this.$npm.uninstall(coreModuleName, { save: true }, this.$projectData.projectDir).wait();
            }
            catch (err) {
                this.$fs.deleteDirectory(platformPath);
                throw err;
            }
            finally {
                spinner.stop();
            }
            this.$logger.out("Project successfully created.");
        }).future()();
    }
    addPlatformCore(platformData, frameworkDir) {
        return (() => {
            let coreModuleData = this.$fs.readJson(path.join(frameworkDir, "../", "package.json"));
            let installedVersion = coreModuleData.version;
            let coreModuleName = coreModuleData.name;
            this.$projectDataService.initialize(this.$projectData.projectDir);
            let customTemplateOptions = this.getPathToPlatformTemplate(this.$options.platformTemplate, platformData.frameworkPackageName).wait();
            let pathToTemplate = customTemplateOptions && customTemplateOptions.pathToTemplate;
            platformData.platformProjectService.createProject(path.resolve(frameworkDir), installedVersion, pathToTemplate).wait();
            platformData.platformProjectService.ensureConfigurationFileInAppResources();
            platformData.platformProjectService.interpolateData().wait();
            platformData.platformProjectService.afterCreateProject(platformData.projectRoot);
            this.applyBaseConfigOption(platformData);
            let frameworkPackageNameData = { version: installedVersion };
            if (customTemplateOptions) {
                frameworkPackageNameData.template = customTemplateOptions.selectedTemplate;
            }
            this.$projectDataService.setValue(platformData.frameworkPackageName, frameworkPackageNameData);
            return coreModuleName;
        }).future()();
    }
    getPathToPlatformTemplate(selectedTemplate, frameworkPackageName) {
        return (() => {
            if (!selectedTemplate) {
                let nativescriptPlatformData = this.$projectDataService.getValue(frameworkPackageName);
                selectedTemplate = nativescriptPlatformData && nativescriptPlatformData.template;
            }
            if (selectedTemplate) {
                let tempDir = temp.mkdirSync("platform-template");
                try {
                    let pathToTemplate = this.$npm.install(selectedTemplate, tempDir).wait()[0];
                    return { selectedTemplate, pathToTemplate };
                }
                catch (err) {
                    this.$logger.trace("Error while trying to install specified template: ", err);
                    this.$errors.failWithoutHelp(`Unable to install platform template ${selectedTemplate}. Make sure the specified value is valid.`);
                }
            }
            return null;
        }).future()();
    }
    getInstalledPlatforms() {
        if (!this.$fs.exists(this.$projectData.platformsDir)) {
            return [];
        }
        let subDirs = this.$fs.readDirectory(this.$projectData.platformsDir);
        return _.filter(subDirs, p => this.$platformsData.platformsNames.indexOf(p) > -1);
    }
    getAvailablePlatforms() {
        let installedPlatforms = this.getInstalledPlatforms();
        return _.filter(this.$platformsData.platformsNames, p => {
            return installedPlatforms.indexOf(p) < 0 && this.isPlatformSupportedForOS(p);
        });
    }
    getPreparedPlatforms() {
        return _.filter(this.$platformsData.platformsNames, p => { return this.isPlatformPrepared(p); });
    }
    preparePlatform(platform, force, skipModulesAndResources) {
        return (() => {
            this.validatePlatform(platform);
            try {
                this.$pluginsService.ensureAllDependenciesAreInstalled().wait();
            }
            catch (err) {
                this.$logger.trace(err);
                this.$errors.failWithoutHelp(`Unable to install dependencies. Make sure your package.json is valid and all dependencies are correct. Error is: ${err.message}`);
            }
            if (platform === "ios") {
                _.each(this.$pluginsService.getAllInstalledPlugins().wait(), (pluginData) => {
                    if (this.$fs.exists(path.join(pluginData.pluginPlatformsFolderPath(platform), "Podfile")) &&
                        !this.$sysInfo.getCocoapodVersion().wait()) {
                        this.$errors.failWithoutHelp(`${pluginData.name} has Podfile and you don't have Cocoapods installed or it is not configured correctly. Please verify Cocoapods can work on your machine.`);
                    }
                });
            }
            this.ensurePlatformInstalled(platform).wait();
            let changeInfo = new project_changes_info_1.ProjectChangesInfo(platform, force, skipModulesAndResources, this.$platformsData, this.$projectData, this.$devicePlatformsConstants, this.$options, this.$fs);
            this._prepareInfo = changeInfo.prepareInfo;
            if (!this.isPlatformPrepared(platform) || changeInfo.hasChanges) {
                this.preparePlatformCore(platform, changeInfo).wait();
                return true;
            }
            return false;
        }).future()();
    }
    preparePlatformCore(platform, changeInfo) {
        return (() => {
            let platformData = this.$platformsData.getPlatformData(platform);
            if (changeInfo.appFilesChanged) {
                this.copyAppFiles(platform).wait();
            }
            if (changeInfo.appResourcesChanged) {
                this.copyAppResources(platform);
                platformData.platformProjectService.prepareProject();
            }
            if (changeInfo.modulesChanged) {
                this.copyTnsModules(platform).wait();
            }
            let directoryPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME);
            let excludedDirs = [constants.APP_RESOURCES_FOLDER_NAME];
            if (!changeInfo.modulesChanged) {
                excludedDirs.push(constants.TNS_MODULES_FOLDER_NAME);
            }
            this.$projectFilesManager.processPlatformSpecificFiles(directoryPath, platform, excludedDirs);
            if (changeInfo.configChanged || changeInfo.modulesChanged) {
                this.applyBaseConfigOption(platformData);
                platformData.platformProjectService.processConfigurationFilesFromAppResources().wait();
            }
            platformData.platformProjectService.interpolateConfigurationFile().wait();
            this.$logger.out("Project successfully prepared (" + platform + ")");
        }).future()();
    }
    copyAppFiles(platform) {
        return (() => {
            let platformData = this.$platformsData.getPlatformData(platform);
            platformData.platformProjectService.ensureConfigurationFileInAppResources();
            let appDestinationDirectoryPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME);
            this.$fs.ensureDirectoryExists(appDestinationDirectoryPath);
            let appSourceDirectoryPath = path.join(this.$projectData.projectDir, constants.APP_FOLDER_NAME);
            const appUpdater = new app_files_updater_1.AppFilesUpdater(appSourceDirectoryPath, appDestinationDirectoryPath, this.$options, this.$fs);
            appUpdater.updateApp(sourceFiles => {
                this.$xmlValidator.validateXmlFiles(sourceFiles);
            });
        }).future()();
    }
    copyAppResources(platform) {
        let platformData = this.$platformsData.getPlatformData(platform);
        let appDestinationDirectoryPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME);
        let appResourcesDirectoryPath = path.join(appDestinationDirectoryPath, constants.APP_RESOURCES_FOLDER_NAME);
        if (this.$fs.exists(appResourcesDirectoryPath)) {
            platformData.platformProjectService.prepareAppResources(appResourcesDirectoryPath);
            let appResourcesDestination = platformData.platformProjectService.getAppResourcesDestinationDirectoryPath();
            this.$fs.ensureDirectoryExists(appResourcesDestination);
            shell.cp("-Rf", path.join(appResourcesDirectoryPath, platformData.normalizedPlatformName, "*"), appResourcesDestination);
            this.$fs.deleteDirectory(appResourcesDirectoryPath);
        }
    }
    copyTnsModules(platform) {
        return (() => {
            let platformData = this.$platformsData.getPlatformData(platform);
            let appDestinationDirectoryPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME);
            let lastModifiedTime = this.$fs.exists(appDestinationDirectoryPath) ? this.$fs.getFsStats(appDestinationDirectoryPath).mtime : null;
            try {
                let tnsModulesDestinationPath = path.join(appDestinationDirectoryPath, constants.TNS_MODULES_FOLDER_NAME);
                this.$nodeModulesBuilder.prepareNodeModules(tnsModulesDestinationPath, platform, lastModifiedTime).wait();
            }
            catch (error) {
                this.$logger.debug(error);
                shell.rm("-rf", appDestinationDirectoryPath);
                this.$errors.failWithoutHelp(`Processing node_modules failed. ${error}`);
            }
        }).future()();
    }
    cleanDestinationApp(platform) {
        return (() => {
            this.ensurePlatformInstalled(platform).wait();
            const appSourceDirectoryPath = path.join(this.$projectData.projectDir, constants.APP_FOLDER_NAME);
            let platformData = this.$platformsData.getPlatformData(platform);
            let appDestinationDirectoryPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME);
            const appUpdater = new app_files_updater_1.AppFilesUpdater(appSourceDirectoryPath, appDestinationDirectoryPath, this.$options, this.$fs);
            appUpdater.cleanDestinationApp();
        }).future()();
    }
    buildPlatform(platform, buildConfig, forceBuild) {
        return (() => {
            let shouldBuild = this.preparePlatform(platform, false).wait();
            let platformData = this.$platformsData.getPlatformData(platform);
            let buildInfoFilePath = this.getBuildOutputPath(platform, platformData, buildConfig);
            let buildInfoFile = path.join(buildInfoFilePath, buildInfoFileName);
            if (!shouldBuild) {
                if (this.$fs.exists(buildInfoFile)) {
                    let buildInfoText = this.$fs.readText(buildInfoFile);
                    shouldBuild = this._prepareInfo.time !== buildInfoText;
                }
                else {
                    shouldBuild = true;
                }
            }
            if (shouldBuild || forceBuild) {
                this.buildPlatformCore(platform, buildConfig).wait();
                this.$fs.writeFile(buildInfoFile, this._prepareInfo.time);
            }
        }).future()();
    }
    buildPlatformCore(platform, buildConfig) {
        return (() => {
            let platformData = this.$platformsData.getPlatformData(platform);
            platformData.platformProjectService.buildProject(platformData.projectRoot, buildConfig).wait();
            this.$logger.out("Project successfully built.");
        }).future()();
    }
    getBuildOutputPath(platform, platformData, buildConfig) {
        let buildForDevice = buildConfig ? buildConfig.buildForDevice : this.$options.forDevice;
        if (platform === this.$devicePlatformsConstants.iOS.toLowerCase()) {
            return buildForDevice ? platformData.deviceBuildOutputPath : platformData.emulatorBuildOutputPath;
        }
        return platformData.deviceBuildOutputPath;
    }
    lastOutputPath(platform, settings) {
        let packageFile;
        let platformData = this.$platformsData.getPlatformData(platform);
        if (settings.isForDevice) {
            packageFile = this.getLatestApplicationPackageForDevice(platformData).packageName;
        }
        else {
            packageFile = this.getLatestApplicationPackageForEmulator(platformData).packageName;
        }
        if (!packageFile || !this.$fs.exists(packageFile)) {
            this.$errors.failWithoutHelp("Unable to find built application. Try 'tns build %s'.", platform);
        }
        return packageFile;
    }
    copyLastOutput(platform, targetPath, settings) {
        platform = platform.toLowerCase();
        targetPath = path.resolve(targetPath);
        let packageFile = this.lastOutputPath(platform, settings);
        this.$fs.ensureDirectoryExists(path.dirname(targetPath));
        if (this.$fs.exists(targetPath) && this.$fs.getFsStats(targetPath).isDirectory()) {
            let sourceFileName = path.basename(packageFile);
            this.$logger.trace(`Specified target path: '${targetPath}' is directory. Same filename will be used: '${sourceFileName}'.`);
            targetPath = path.join(targetPath, sourceFileName);
        }
        this.$fs.copyFile(packageFile, targetPath);
        this.$logger.info(`Copied file '${packageFile}' to '${targetPath}'.`);
    }
    removePlatforms(platforms) {
        this.$projectDataService.initialize(this.$projectData.projectDir);
        _.each(platforms, platform => {
            this.validatePlatformInstalled(platform);
            let platformData = this.$platformsData.getPlatformData(platform);
            let platformDir = path.join(this.$projectData.platformsDir, platform);
            this.$fs.deleteDirectory(platformDir);
            this.$projectDataService.removeProperty(platformData.frameworkPackageName);
            this.$logger.out(`Platform ${platform} successfully removed.`);
        });
    }
    updatePlatforms(platforms) {
        return (() => {
            _.each(platforms, platformParam => {
                let data = platformParam.split("@"), platform = data[0], version = data[1];
                if (this.isPlatformInstalled(platform)) {
                    this.updatePlatform(platform, version).wait();
                }
                else {
                    this.addPlatform(platformParam).wait();
                }
            });
        }).future()();
    }
    deployPlatform(platform) {
        return (() => {
            let platformData = this.$platformsData.getPlatformData(platform);
            this.$devicesService.initialize({ platform: platform, deviceId: this.$options.device }).wait();
            let packageFileDict = {};
            let action = (device) => {
                return (() => {
                    let packageFileKey = this.getPackageFileKey(device);
                    let packageFile = packageFileDict[packageFileKey];
                    if (!packageFile) {
                        let buildConfig = {};
                        let isSimulator = this.$devicesService.isiOSSimulator(device);
                        buildConfig.buildForDevice = !isSimulator;
                        this.buildPlatform(platform, buildConfig, false).wait();
                        if (isSimulator) {
                            packageFile = this.getLatestApplicationPackageForEmulator(platformData).packageName;
                        }
                        else {
                            packageFile = this.getLatestApplicationPackageForDevice(platformData).packageName;
                        }
                    }
                    platformData.platformProjectService.deploy(device.deviceInfo.identifier).wait();
                    device.applicationManager.reinstallApplication(this.$projectData.projectId, packageFile).wait();
                    this.$logger.info(`Successfully deployed on device with identifier '${device.deviceInfo.identifier}'.`);
                    packageFileDict[packageFileKey] = packageFile;
                }).future()();
            };
            this.$devicesService.execute(action, this.getCanExecuteAction(platform)).wait();
        }).future()();
    }
    runPlatform(platform) {
        if (this.$options.avd) {
            this.$logger.warn(`Option --avd is no longer supported. Please use --device instead!`);
            return Future.fromResult();
        }
        return (() => {
            this.deployPlatform(platform).wait();
            let action = (device) => device.applicationManager.startApplication(this.$projectData.projectId);
            this.$devicesService.execute(action, this.getCanExecuteAction(platform)).wait();
        }).future()();
    }
    emulatePlatform(platform) {
        if (this.$options.availableDevices) {
            return $injector.resolveCommand("device").execute([platform]);
        }
        return this.runPlatform(platform);
    }
    getPackageFileKey(device) {
        if (this.$mobileHelper.isAndroidPlatform(device.deviceInfo.platform)) {
            return device.deviceInfo.platform.toLowerCase();
        }
        return device.deviceInfo.platform.toLowerCase() + device.deviceInfo.type;
    }
    getCanExecuteAction(platform) {
        let canExecute = (currentDevice) => {
            if (this.$options.device && currentDevice && currentDevice.deviceInfo) {
                let device = this.$devicesService.getDeviceByDeviceOption();
                if (device && device.deviceInfo) {
                    return currentDevice.deviceInfo.identifier === device.deviceInfo.identifier;
                }
            }
            if (this.$mobileHelper.isiOSPlatform(platform) && this.$hostInfo.isDarwin) {
                if (this.$devicesService.isOnlyiOSSimultorRunning() || this.$options.emulator || this.$devicesService.isiOSSimulator(currentDevice)) {
                    return true;
                }
                return this.$devicesService.isiOSDevice(currentDevice);
            }
            return true;
        };
        return canExecute;
    }
    validatePlatform(platform) {
        if (!platform) {
            this.$errors.fail("No platform specified.");
        }
        platform = platform.split("@")[0].toLowerCase();
        if (!this.isValidPlatform(platform)) {
            this.$errors.fail("Invalid platform %s. Valid platforms are %s.", platform, helpers.formatListOfNames(this.$platformsData.platformsNames));
        }
        if (!this.isPlatformSupportedForOS(platform)) {
            this.$errors.fail("Applications for platform %s can not be built on this OS - %s", platform, process.platform);
        }
    }
    validatePlatformInstalled(platform) {
        this.validatePlatform(platform);
        if (!this.isPlatformInstalled(platform)) {
            this.$errors.fail("The platform %s is not added to this project. Please use 'tns platform add <platform>'", platform);
        }
    }
    ensurePlatformInstalled(platform) {
        return (() => {
            if (!this.isPlatformInstalled(platform)) {
                this.addPlatform(platform).wait();
            }
        }).future()();
    }
    isPlatformInstalled(platform) {
        return this.$fs.exists(path.join(this.$projectData.platformsDir, platform.toLowerCase()));
    }
    isValidPlatform(platform) {
        return this.$platformsData.getPlatformData(platform);
    }
    isPlatformSupportedForOS(platform) {
        let targetedOS = this.$platformsData.getPlatformData(platform).targetedOS;
        let res = !targetedOS || targetedOS.indexOf("*") >= 0 || targetedOS.indexOf(process.platform) >= 0;
        return res;
    }
    isPlatformPrepared(platform) {
        let platformData = this.$platformsData.getPlatformData(platform);
        return platformData.platformProjectService.isPlatformPrepared(platformData.projectRoot);
    }
    getApplicationPackages(buildOutputPath, validPackageNames) {
        let candidates = this.$fs.readDirectory(buildOutputPath);
        let packages = _.filter(candidates, candidate => {
            return _.includes(validPackageNames, candidate);
        }).map(currentPackage => {
            currentPackage = path.join(buildOutputPath, currentPackage);
            return {
                packageName: currentPackage,
                time: this.$fs.getFsStats(currentPackage).mtime
            };
        });
        return packages;
    }
    getLatestApplicationPackage(buildOutputPath, validPackageNames) {
        let packages = this.getApplicationPackages(buildOutputPath, validPackageNames);
        if (packages.length === 0) {
            let packageExtName = path.extname(validPackageNames[0]);
            this.$errors.fail("No %s found in %s directory", packageExtName, buildOutputPath);
        }
        packages = _.sortBy(packages, pkg => pkg.time).reverse();
        return packages[0];
    }
    getLatestApplicationPackageForDevice(platformData) {
        return this.getLatestApplicationPackage(platformData.deviceBuildOutputPath, platformData.validPackageNamesForDevice);
    }
    getLatestApplicationPackageForEmulator(platformData) {
        return this.getLatestApplicationPackage(platformData.emulatorBuildOutputPath || platformData.deviceBuildOutputPath, platformData.validPackageNamesForEmulator || platformData.validPackageNamesForDevice);
    }
    updatePlatform(platform, version) {
        return (() => {
            let platformData = this.$platformsData.getPlatformData(platform);
            this.$projectDataService.initialize(this.$projectData.projectDir);
            let data = this.$projectDataService.getValue(platformData.frameworkPackageName);
            let currentVersion = data && data.version ? data.version : "0.2.0";
            let newVersion = version === constants.PackageVersion.NEXT ?
                this.$npmInstallationManager.getNextVersion(platformData.frameworkPackageName).wait() :
                version || this.$npmInstallationManager.getLatestCompatibleVersion(platformData.frameworkPackageName).wait();
            let installedModuleDir = this.$npmInstallationManager.install(platformData.frameworkPackageName, this.$projectData.projectDir, { version: newVersion, dependencyType: "save" }).wait();
            let cachedPackageData = this.$fs.readJson(path.join(installedModuleDir, "package.json"));
            newVersion = (cachedPackageData && cachedPackageData.version) || newVersion;
            let canUpdate = platformData.platformProjectService.canUpdatePlatform(installedModuleDir);
            this.$npm.uninstall(platformData.frameworkPackageName, { save: true }, this.$projectData.projectDir).wait();
            if (canUpdate) {
                if (!semver.valid(newVersion)) {
                    this.$errors.fail("The version %s is not valid. The version should consists from 3 parts separated by dot.", newVersion);
                }
                if (!semver.gt(currentVersion, newVersion)) {
                    this.updatePlatformCore(platformData, currentVersion, newVersion, canUpdate).wait();
                }
                else if (semver.eq(currentVersion, newVersion)) {
                    this.$errors.fail("Current and new version are the same.");
                }
                else {
                    this.$errors.fail(`Your current version: ${currentVersion} is higher than the one you're trying to install ${newVersion}.`);
                }
            }
            else {
                this.$errors.failWithoutHelp("Native Platform cannot be updated.");
            }
        }).future()();
    }
    updatePlatformCore(platformData, currentVersion, newVersion, canUpdate) {
        return (() => {
            let packageName = platformData.normalizedPlatformName.toLowerCase();
            this.removePlatforms([packageName]);
            packageName = newVersion ? `${packageName}@${newVersion}` : packageName;
            this.addPlatform(packageName).wait();
            this.$logger.out("Successfully updated to version ", newVersion);
        }).future()();
    }
    applyBaseConfigOption(platformData) {
        if (this.$options.baseConfig) {
            let newConfigFile = path.resolve(this.$options.baseConfig);
            this.$logger.trace(`Replacing '${platformData.configurationFilePath}' with '${newConfigFile}'.`);
            this.$fs.copyFile(newConfigFile, platformData.configurationFilePath);
        }
    }
}
__decorate([
    helpers.hook('prepare')
], PlatformService.prototype, "preparePlatformCore", null);
exports.PlatformService = PlatformService;
$injector.register("platformService", PlatformService);
