"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.TypingsCommand = void 0;
const yok_1 = require("../common/yok");
const path = require("path");
class TypingsCommand {
    constructor($logger, $options, $fs, $projectData, $mobileHelper, $childProcess, $hostInfo, $staticConfig) {
        this.$logger = $logger;
        this.$options = $options;
        this.$fs = $fs;
        this.$projectData = $projectData;
        this.$mobileHelper = $mobileHelper;
        this.$childProcess = $childProcess;
        this.$hostInfo = $hostInfo;
        this.$staticConfig = $staticConfig;
        this.allowedParameters = [];
    }
    execute(args) {
        return __awaiter(this, void 0, void 0, function* () {
            const platform = args[0];
            let result;
            if (this.$mobileHelper.isAndroidPlatform(platform)) {
                result = yield this.handleAndroidTypings();
            }
            else if (this.$mobileHelper.isiOSPlatform(platform)) {
                result = yield this.handleiOSTypings();
            }
            let typingsFolder = "./typings";
            if (this.$options.copyTo) {
                this.$fs.copyFile(path.resolve(this.$projectData.projectDir, "typings"), this.$options.copyTo);
                typingsFolder = this.$options.copyTo;
            }
            if (result !== false) {
                this.$logger.info("Typings have been generated in the following directory:", typingsFolder);
            }
        });
    }
    canExecute(args) {
        return __awaiter(this, void 0, void 0, function* () {
            const platform = args[0];
            this.$mobileHelper.validatePlatformName(platform);
            return true;
        });
    }
    handleAndroidTypings() {
        return __awaiter(this, void 0, void 0, function* () {
            if (!(this.$options.jar || this.$options.aar)) {
                this.$logger.warn([
                    "No .jar or .aar file specified. Please specify at least one of the following:",
                    "  - path to .jar file with --jar <jar>",
                    "  - path to .aar file with --aar <aar>",
                ].join("\n"));
                return false;
            }
            this.$fs.ensureDirectoryExists(path.resolve(this.$projectData.projectDir, "typings", "android"));
            const dtsGeneratorPath = path.resolve(this.$projectData.projectDir, "platforms", "android", "build-tools", "dts-generator.jar");
            if (!this.$fs.exists(dtsGeneratorPath)) {
                this.$logger.warn("No platforms folder found, preparing project now...");
                yield this.$childProcess.spawnFromEvent(this.$hostInfo.isWindows ? "ns.cmd" : "ns", ["prepare", "android"], "exit", { stdio: "inherit" });
            }
            const asArray = (input) => {
                if (!input) {
                    return [];
                }
                if (typeof input === "string") {
                    return [input];
                }
                return input;
            };
            const inputs = [
                ...asArray(this.$options.jar),
                ...asArray(this.$options.aar),
            ];
            yield this.$childProcess.spawnFromEvent("java", [
                "-jar",
                dtsGeneratorPath,
                "-input",
                ...inputs,
                "-output",
                path.resolve(this.$projectData.projectDir, "typings", "android"),
            ], "exit", { stdio: "inherit" });
        });
    }
    handleiOSTypings() {
        return __awaiter(this, void 0, void 0, function* () {
            if (this.$options.filter !== undefined) {
                this.$logger.warn("--filter flag is not supported yet.");
            }
            this.$fs.ensureDirectoryExists(path.resolve(this.$projectData.projectDir, "typings", "ios"));
            yield this.$childProcess.spawnFromEvent("node", [this.$staticConfig.cliBinPath, "build", "ios"], "exit", {
                env: Object.assign(Object.assign({}, process.env), { TNS_TYPESCRIPT_DECLARATIONS_PATH: path.resolve(this.$projectData.projectDir, "typings", "ios") }),
                stdio: "inherit",
            });
        });
    }
}
exports.TypingsCommand = TypingsCommand;
yok_1.injector.registerCommand("typings", TypingsCommand);
