"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    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) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PlatformController = void 0;
const path = require("path");
const yok_1 = require("../common/yok");
class PlatformController {
    constructor($addPlatformService, $errors, $fs, $logger, $packageInstallationManager, $projectDataService, $platformsDataService, $projectChangesService) {
        this.$addPlatformService = $addPlatformService;
        this.$errors = $errors;
        this.$fs = $fs;
        this.$logger = $logger;
        this.$packageInstallationManager = $packageInstallationManager;
        this.$projectDataService = $projectDataService;
        this.$platformsDataService = $platformsDataService;
        this.$projectChangesService = $projectChangesService;
    }
    addPlatform(addPlatformData) {
        return __awaiter(this, void 0, void 0, function* () {
            const [platform, version] = addPlatformData.platform
                .toLowerCase()
                .split("@");
            const projectData = this.$projectDataService.getProjectData(addPlatformData.projectDir);
            const platformData = this.$platformsDataService.getPlatformData(platform, projectData);
            this.$logger.trace(`Creating NativeScript project for the ${platform} platform`);
            this.$logger.trace(`Path: ${platformData.projectRoot}`);
            this.$logger.trace(`Package: ${projectData.projectIdentifiers[platform]}`);
            this.$logger.trace(`Name: ${projectData.projectName}`);
            this.$logger.info("Copying template files...");
            const packageToInstall = yield this.getPackageToInstall(platformData, projectData, addPlatformData.frameworkPath, version);
            this.$logger.trace("Determined package to install is", packageToInstall);
            const installedPlatformVersion = yield this.$addPlatformService.addPlatformSafe(projectData, platformData, packageToInstall, addPlatformData);
            this.$fs.ensureDirectoryExists(path.join(projectData.platformsDir, platform));
            this.$logger.info(`Platform ${platform} successfully added. v${installedPlatformVersion}`);
        });
    }
    addPlatformIfNeeded(addPlatformData) {
        return __awaiter(this, void 0, void 0, function* () {
            const [platform] = addPlatformData.platform.toLowerCase().split("@");
            const projectData = this.$projectDataService.getProjectData(addPlatformData.projectDir);
            const platformData = this.$platformsDataService.getPlatformData(platform, projectData);
            const shouldAddPlatform = this.shouldAddPlatform(platformData, projectData, addPlatformData.nativePrepare);
            if (shouldAddPlatform) {
                yield this.addPlatform(addPlatformData);
            }
        });
    }
    getPackageToInstall(platformData, projectData, frameworkPath, version) {
        return __awaiter(this, void 0, void 0, function* () {
            let result = null;
            if (frameworkPath) {
                if (!this.$fs.exists(frameworkPath)) {
                    this.$errors.fail(`Invalid frameworkPath: ${frameworkPath}. Please ensure the specified frameworkPath exists.`);
                }
                result = "file:" + path.resolve(frameworkPath);
            }
            else {
                const desiredRuntimePackage = this.$projectDataService.getRuntimePackage(projectData.projectDir, platformData.platformNameLowerCase);
                if (version) {
                    desiredRuntimePackage.version = version;
                }
                if (!desiredRuntimePackage.version) {
                    desiredRuntimePackage.version = yield this.$packageInstallationManager.getLatestCompatibleVersion(desiredRuntimePackage.name);
                }
                result = `${desiredRuntimePackage.name}@${desiredRuntimePackage.version}`;
            }
            return result;
        });
    }
    shouldAddPlatform(platformData, projectData, nativePrepare) {
        const platformName = platformData.platformNameLowerCase;
        const hasPlatformDirectory = this.$fs.exists(path.join(projectData.platformsDir, platformName));
        const shouldAddNativePlatform = !nativePrepare || !nativePrepare.skipNativePrepare;
        const prepareInfo = this.$projectChangesService.getPrepareInfo(platformData);
        const requiresNativePlatformAdd = prepareInfo &&
            prepareInfo.nativePlatformStatus ===
                "1";
        const result = !hasPlatformDirectory ||
            (shouldAddNativePlatform && requiresNativePlatformAdd);
        return !!result;
    }
}
exports.PlatformController = PlatformController;
yok_1.injector.register("platformController", PlatformController);
