"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments)).next());
    });
};
const mobileprovision = require("ios-mobileprovision-finder");
const helpers_1 = require("../common/helpers");
const months = ["Jan", "Feb", "Marc", "Apr", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"];
function formatDate(date) {
    return `${date.getDay()} ${months[date.getMonth()]} ${date.getFullYear()}`;
}
class IOSProvisionService {
    constructor($logger, $options, $devicesService, $projectData, $mobileHelper) {
        this.$logger = $logger;
        this.$options = $options;
        this.$devicesService = $devicesService;
        this.$projectData = $projectData;
        this.$mobileHelper = $mobileHelper;
    }
    pick(uuidOrName) {
        return __awaiter(this, void 0, void 0, function* () {
            const match = (yield this.queryProvisioningProfilesAndDevices()).match;
            return match.eligable.find(prov => prov.UUID === uuidOrName)
                || match.eligable.find(prov => prov.Name === uuidOrName)
                || match.nonEligable.find(prov => prov.UUID === uuidOrName)
                || match.nonEligable.find(prov => prov.Name === uuidOrName);
        });
    }
    list() {
        return __awaiter(this, void 0, void 0, function* () {
            const data = yield this.queryProvisioningProfilesAndDevices();
            const devices = data.devices;
            const match = data.match;
            function formatSupportedDeviceCount(prov) {
                if (devices.length > 0 && prov.Type === "Development") {
                    return prov.ProvisionedDevices.reduce((count, device) => count + (devices.indexOf(device) >= 0 ? 1 : 0), 0) + "/" + devices.length + " targets";
                }
                else {
                    return "";
                }
            }
            function formatTotalDeviceCount(prov) {
                if (prov.Type === "Development" && prov.ProvisionedDevices) {
                    return prov.ProvisionedDevices.length + " total";
                }
                else if (prov.Type === "AdHoc") {
                    return "all";
                }
                else {
                    return "";
                }
            }
            const table = helpers_1.createTable(["Provision Name / Provision UUID / App Id", "Team", "Type / Due", "Devices"], []);
            function pushProvision(prov) {
                table.push(["", "", "", ""]);
                table.push(["\"" + prov.Name + "\"", prov.TeamName, prov.Type, formatTotalDeviceCount(prov)]);
                table.push([prov.UUID, prov.TeamIdentifier && prov.TeamIdentifier.length > 0 ? "(" + prov.TeamIdentifier[0] + ")" : "", formatDate(prov.ExpirationDate), formatSupportedDeviceCount(prov)]);
                table.push([prov.Entitlements["application-identifier"], "", "", ""]);
            }
            match.eligable.forEach(prov => pushProvision(prov));
            this.$logger.out(table.toString());
            this.$logger.out();
            this.$logger.out("There are also " + match.nonEligable.length + " non-eligable provisioning profiles.");
            this.$logger.out();
        });
    }
    queryProvisioningProfilesAndDevices() {
        return __awaiter(this, void 0, void 0, function* () {
            const certificates = mobileprovision.cert.read();
            const provisions = mobileprovision.provision.read();
            const query = {
                Certificates: certificates.valid,
                Unique: true,
                AppId: this.$projectData.projectId
            };
            let devices = [];
            if (this.$options.device) {
                devices = [this.$options.device];
            }
            else {
                yield this.$devicesService.initialize({
                    platform: "ios"
                });
                devices = _(this.$devicesService.getDeviceInstances())
                    .filter(d => this.$mobileHelper.isiOSPlatform(d.deviceInfo.platform))
                    .map(d => d.deviceInfo.identifier)
                    .toJSON();
            }
            const match = mobileprovision.provision.select(provisions, query);
            return { devices, match };
        });
    }
}
exports.IOSProvisionService = IOSProvisionService;
$injector.register("iOSProvisionService", IOSProvisionService);
