"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, $mobileHelper) {
        this.$addPlatformService = $addPlatformService;
        this.$errors = $errors;
        this.$fs = $fs;
        this.$logger = $logger;
        this.$packageInstallationManager = $packageInstallationManager;
        this.$projectDataService = $projectDataService;
        this.$platformsDataService = $platformsDataService;
        this.$projectChangesService = $projectChangesService;
        this.$mobileHelper = $mobileHelper;
    }
    addPlatform(addPlatformData, projectData) {
        return __awaiter(this, void 0, void 0, function* () {
            const [platform, version] = addPlatformData.platform
                .toLowerCase()
                .split("@");
            projectData !== null && projectData !== void 0 ? projectData : (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));
            if (this.$mobileHelper.isAndroidPlatform(platform)) {
                const gradlePropertiesPath = path.resolve(platformData.projectRoot, "gradle.properties");
                const commentHeader = "# App configuration";
                const appPath = projectData.getAppDirectoryRelativePath();
                const appResourcesPath = projectData.getAppResourcesRelativeDirectoryPath();
                let gradlePropertiesContents = "";
                if (this.$fs.exists(gradlePropertiesPath)) {
                    gradlePropertiesContents = this.$fs
                        .readFile(gradlePropertiesPath)
                        .toString();
                }
                if (!gradlePropertiesContents.includes(commentHeader)) {
                    const dataToWrite = [
                        "",
                        "",
                        commentHeader,
                        `appPath = ${appPath}`,
                        `appResourcesPath = ${appResourcesPath}`,
                        "",
                    ].join("\n");
                    gradlePropertiesContents += dataToWrite;
                    this.$logger.trace("Updated gradle.properties with project data...");
                    this.$fs.writeFile(gradlePropertiesPath, gradlePropertiesContents);
                }
            }
            this.$logger.info(`Platform ${platform} successfully added. v${installedPlatformVersion}`);
        });
    }
    addPlatformIfNeeded(addPlatformData, projectData) {
        return __awaiter(this, void 0, void 0, function* () {
            if (addPlatformData.hostProjectPath) {
                this.$logger.trace("Not adding platform because --hostProjectPath is provided.");
                return;
            }
            const [platform] = addPlatformData.platform.toLowerCase().split("@");
            projectData !== null && projectData !== void 0 ? projectData : (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, projectData);
            }
        });
    }
    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) {
                    // if no version is explicitly added, then we use the latest
                    desiredRuntimePackage.version =
                        yield this.$packageInstallationManager.getLatestCompatibleVersion(desiredRuntimePackage.name);
                }
                // const currentPlatformData = this.$projectDataService.getNSValue(projectData.projectDir, platformData.frameworkPackageName);
                // version = (currentPlatformData && currentPlatformData.version) ||
                // 	await this.$packageInstallationManager.getLatestCompatibleVersion(platformData.frameworkPackageName);
                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" /* NativePlatformStatus.requiresPlatformAdd */;
        const shouldAddPlatform = !hasPlatformDirectory ||
            (shouldAddNativePlatform && requiresNativePlatformAdd);
        if (hasPlatformDirectory && !shouldAddPlatform) {
            const platformDirectoryItemCount = this.$fs.readDirectory(path.join(projectData.platformsDir, platformName)).length;
            // 2 is a magic number to approximate a valid platform folder
            // any valid platform should contain at least 2 files/folders
            // we choose 2 to avoid false-positives due to system files like .DS_Store etc.
            if (platformDirectoryItemCount <= 2) {
                this.$logger.warn(`The platforms/${platformName} folder appears to be invalid. If the build fails, run 'ns clean' and rebuild the app.`, { wrapMessageWithBorders: true });
            }
        }
        return !!shouldAddPlatform;
    }
}
exports.PlatformController = PlatformController;
yok_1.injector.register("platformController", PlatformController);
//# sourceMappingURL=platform-controller.js.map