"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.BuildArtifactsService = void 0;
const path = require("path");
const yok_1 = require("../common/yok");
const _ = require("lodash");
class BuildArtifactsService {
    constructor($errors, $fs, $logger) {
        this.$errors = $errors;
        this.$fs = $fs;
        this.$logger = $logger;
    }
    getLatestAppPackagePath(platformData, buildOutputOptions) {
        return __awaiter(this, void 0, void 0, function* () {
            const outputPath = buildOutputOptions.outputPath ||
                platformData.getBuildOutputPath(buildOutputOptions);
            const applicationPackage = this.getLatestApplicationPackage(outputPath, platformData.getValidBuildOutputData(buildOutputOptions));
            const packageFile = applicationPackage.packageName;
            if (!packageFile || !this.$fs.exists(packageFile)) {
                this.$errors.fail(`Unable to find built application. Try 'tns build ${platformData.platformNameLowerCase}'.`);
            }
            return packageFile;
        });
    }
    getAllAppPackages(buildOutputPath, validBuildOutputData) {
        const rootFiles = this.$fs
            .readDirectory(buildOutputPath)
            .map((filename) => path.join(buildOutputPath, filename));
        let result = this.getApplicationPackagesCore(rootFiles, validBuildOutputData.packageNames);
        if (result) {
            return result;
        }
        const candidates = this.$fs.enumerateFilesInDirectorySync(buildOutputPath);
        result = this.getApplicationPackagesCore(candidates, validBuildOutputData.packageNames);
        if (result) {
            return result;
        }
        if (validBuildOutputData.regexes && validBuildOutputData.regexes.length) {
            const packages = candidates.filter((filepath) => _.some(validBuildOutputData.regexes, (regex) => regex.test(path.basename(filepath))));
            return this.createApplicationPackages(packages);
        }
        return [];
    }
    copyLatestAppPackage(targetPath, platformData, buildOutputOptions) {
        targetPath = path.resolve(targetPath);
        const outputPath = buildOutputOptions.outputPath ||
            platformData.getBuildOutputPath(buildOutputOptions);
        const applicationPackage = this.getLatestApplicationPackage(outputPath, platformData.getValidBuildOutputData(buildOutputOptions));
        const packageFile = applicationPackage.packageName;
        this.$fs.ensureDirectoryExists(path.dirname(targetPath));
        if (this.$fs.exists(targetPath) &&
            this.$fs.getFsStats(targetPath).isDirectory()) {
            const 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}'.`);
    }
    getLatestApplicationPackage(buildOutputPath, validBuildOutputData) {
        let packages = this.getAllAppPackages(buildOutputPath, validBuildOutputData);
        const packageExtName = path.extname(validBuildOutputData.packageNames[0]);
        if (packages.length === 0) {
            this.$errors.fail(`No ${packageExtName} found in ${buildOutputPath} directory.`);
        }
        if (packages.length > 1) {
            this.$logger.warn(`More than one ${packageExtName} found in ${buildOutputPath} directory. Using the last one produced from build.`);
        }
        packages = _.sortBy(packages, (pkg) => pkg.time).reverse();
        return packages[0];
    }
    getApplicationPackagesCore(candidates, validPackageNames) {
        const packages = candidates.filter((filePath) => _.includes(validPackageNames, path.basename(filePath)));
        if (packages.length > 0) {
            return this.createApplicationPackages(packages);
        }
        return null;
    }
    createApplicationPackages(packages) {
        return packages.map((packageName) => {
            return {
                packageName,
                time: this.$fs.getFsStats(packageName).mtime,
            };
        });
    }
}
exports.BuildArtifactsService = BuildArtifactsService;
yok_1.injector.register("buildArtifactsService", BuildArtifactsService);
