"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;
};
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.AndroidToolsInfo = void 0;
const path = require("path");
const _ = require("lodash");
const decorators_1 = require("./common/decorators");
const doctor_1 = require("@nativescript/doctor");
const yok_1 = require("./common/yok");
class AndroidToolsInfo {
    constructor($errors, $logger, $options, $staticConfig) {
        this.$errors = $errors;
        this.$logger = $logger;
        this.$options = $options;
        this.$staticConfig = $staticConfig;
    }
    getToolsInfo(config) {
        const infoData = (doctor_1.androidToolsInfo.getToolsInfo({ projectDir: config.projectDir }));
        infoData.androidHomeEnvVar = doctor_1.androidToolsInfo.androidHome;
        infoData.compileSdkVersion = this.getCompileSdkVersion(infoData.installedTargets, infoData.compileSdkVersion);
        infoData.targetSdkVersion = this.getTargetSdk(infoData.compileSdkVersion);
        infoData.generateTypings = this.shouldGenerateTypings();
        this.$logger.trace("Installed Android Targets are: ", infoData.installedTargets);
        this.$logger.trace("Selected buildToolsVersion is:", infoData.buildToolsVersion);
        return infoData;
    }
    validateInfo(options) {
        let detectedErrors = false;
        const showWarningsAsErrors = options && options.showWarningsAsErrors;
        const isAndroidHomeValid = this.validateAndroidHomeEnvVariable(options);
        detectedErrors =
            doctor_1.androidToolsInfo
                .validateInfo({ projectDir: options.projectDir })
                .map((warning) => this.printMessage(warning.warning, showWarningsAsErrors)).length > 0;
        if (options && options.validateTargetSdk) {
            detectedErrors = this.validateTargetSdk(options);
        }
        return detectedErrors || !isAndroidHomeValid;
    }
    validateTargetSdk(options) {
        let detectedErrors = false;
        const toolsInfoData = this.getToolsInfo({ projectDir: options.projectDir });
        const targetSdk = toolsInfoData.targetSdkVersion;
        detectedErrors =
            doctor_1.androidToolsInfo
                .validateMinSupportedTargetSdk({
                targetSdk,
                projectDir: options.projectDir,
            })
                .map((warning) => this.printMessage(warning.warning, options.showWarningsAsErrors)).length > 0;
        if (!detectedErrors) {
            doctor_1.androidToolsInfo
                .validataMaxSupportedTargetSdk({
                targetSdk,
                projectDir: options.projectDir,
            })
                .map((warning) => this.$logger.warn(warning.warning));
        }
        return detectedErrors;
    }
    validateJavacVersion(installedJavacVersion, options) {
        const showWarningsAsErrors = options && options.showWarningsAsErrors;
        return (doctor_1.androidToolsInfo
            .validateJavacVersion(installedJavacVersion)
            .map((warning) => this.printMessage(warning.warning, showWarningsAsErrors)).length > 0);
    }
    getPathToAdbFromAndroidHome() {
        return __awaiter(this, void 0, void 0, function* () {
            try {
                return doctor_1.androidToolsInfo.getPathToAdbFromAndroidHome();
            }
            catch (err) {
                // adb does not exist, so ANDROID_HOME is not set correctly
                // try getting default adb path (included in CLI package)
                this.$logger.trace(`Error while executing '${path.join(doctor_1.androidToolsInfo.androidHome, "platform-tools", "adb")} help'. Error is: ${err.message}`);
            }
            return null;
        });
    }
    validateAndroidHomeEnvVariable(options) {
        const showWarningsAsErrors = options && options.showWarningsAsErrors;
        return (doctor_1.androidToolsInfo
            .validateAndroidHomeEnvVariable()
            .map((warning) => this.printMessage(warning.warning, showWarningsAsErrors)).length > 0);
    }
    shouldGenerateTypings() {
        return this.$options.androidTypings;
    }
    /**
     * Prints messages on the screen. In case the showWarningsAsErrors flag is set to true, warnings are shown, else - errors.
     * Uses logger.warn for warnings and errors.failWithoutHelp when erros must be shown.
     * In case additional details must be shown as info message, use the second parameter.
     * NOTE: The additional information will not be printed when showWarningsAsErrors flag is set.
     * @param  {string} msg The message that will be shown as warning or error.
     * @return {void}
     */
    printMessage(msg, showWarningsAsErrors) {
        if (showWarningsAsErrors) {
            this.$errors.fail(msg);
        }
        else {
            this.$logger.warn(msg);
        }
    }
    getCompileSdkVersion(installedTargets, latestCompileSdk) {
        const userSpecifiedCompileSdk = this.$options.compileSdk;
        if (userSpecifiedCompileSdk) {
            const androidCompileSdk = `${doctor_1.androidToolsInfo.ANDROID_TARGET_PREFIX}-${userSpecifiedCompileSdk}`;
            if (!_.includes(installedTargets, androidCompileSdk)) {
                this.$errors.fail(`You have specified '${userSpecifiedCompileSdk}' for compile sdk, but it is not installed on your system.`);
            }
            return userSpecifiedCompileSdk;
        }
        return latestCompileSdk;
    }
    // TODO check if still needed
    getTargetSdk(compileSdk) {
        const targetSdk = this.$options.sdk
            ? parseInt(this.$options.sdk)
            : compileSdk;
        this.$logger.trace(`Selected targetSdk is: ${targetSdk}`);
        return targetSdk;
    }
}
__decorate([
    (0, decorators_1.cache)()
], AndroidToolsInfo.prototype, "getToolsInfo", null);
__decorate([
    (0, decorators_1.cache)()
], AndroidToolsInfo.prototype, "validateAndroidHomeEnvVariable", null);
exports.AndroidToolsInfo = AndroidToolsInfo;
yok_1.injector.register("androidToolsInfo", AndroidToolsInfo);
//# sourceMappingURL=android-tools-info.js.map