"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 });
const helpers_1 = require("../common/helpers");
const constants_1 = require("../constants");
const yok_1 = require("../common/yok");
class TestCommandBase {
    constructor() {
        this.allowedParameters = [];
        this.dashedOptions = {
            hmr: { type: "boolean", default: false, hasSensitiveValue: false },
        };
    }
    execute(args) {
        return __awaiter(this, void 0, void 0, function* () {
            let devices = [];
            if (this.$options.debugBrk) {
                yield this.$devicesService.initialize({
                    platform: this.platform,
                    deviceId: this.$options.device,
                    emulator: this.$options.emulator,
                    skipInferPlatform: !this.platform,
                    sdk: this.$options.sdk,
                });
                const selectedDeviceForDebug = yield this.$devicesService.pickSingleDevice({
                    onlyEmulators: this.$options.emulator,
                    onlyDevices: this.$options.forDevice,
                    deviceId: this.$options.device,
                });
                devices = [selectedDeviceForDebug];
            }
            else {
                devices = yield this.$liveSyncCommandHelper.getDeviceInstances(this.platform);
            }
            if (!this.$options.env) {
                this.$options.env = {};
            }
            this.$options.env.unitTesting = true;
            const liveSyncInfo = this.$liveSyncCommandHelper.getLiveSyncData(this.$projectData.projectDir);
            const deviceDebugMap = {};
            devices.forEach((device) => (deviceDebugMap[device.deviceInfo.identifier] = this.$options.debugBrk));
            const deviceDescriptors = yield this.$liveSyncCommandHelper.createDeviceDescriptors(devices, this.platform, { deviceDebugMap });
            yield this.$testExecutionService.startKarmaServer(this.platform, liveSyncInfo, deviceDescriptors);
            process.exit(0);
        });
    }
    canExecute(args) {
        return __awaiter(this, void 0, void 0, function* () {
            if (!this.$options.force) {
                if (this.$options.hmr) {
                    this.$errors.fail("The `--hmr` option is not supported for this command.");
                }
                yield this.$migrateController.validate({
                    projectDir: this.$projectData.projectDir,
                    platforms: [this.platform],
                });
            }
            this.$projectData.initializeProjectData();
            this.$analyticsService.setShouldDispose(this.$options.justlaunch || !this.$options.watch);
            this.$cleanupService.setShouldDispose(this.$options.justlaunch || !this.$options.watch);
            const output = yield this.$platformEnvironmentRequirements.checkEnvironmentRequirements({
                platform: this.platform,
                projectDir: this.$projectData.projectDir,
                options: this.$options,
                notConfiguredEnvOptions: {
                    hideSyncToPreviewAppOption: true,
                },
            });
            const canStartKarmaServer = yield this.$testExecutionService.canStartKarmaServer(this.$projectData);
            if (!canStartKarmaServer) {
                this.$errors.fail({
                    formatStr: "Error: In order to run unit tests, your project must already be configured by running $ ns test init.",
                    errorCode: 133,
                });
            }
            return output.canExecute && canStartKarmaServer;
        });
    }
}
class TestAndroidCommand extends TestCommandBase {
    constructor($projectData, $testExecutionService, $analyticsService, $options, $platformEnvironmentRequirements, $errors, $cleanupService, $liveSyncCommandHelper, $devicesService, $migrateController) {
        super();
        this.$projectData = $projectData;
        this.$testExecutionService = $testExecutionService;
        this.$analyticsService = $analyticsService;
        this.$options = $options;
        this.$platformEnvironmentRequirements = $platformEnvironmentRequirements;
        this.$errors = $errors;
        this.$cleanupService = $cleanupService;
        this.$liveSyncCommandHelper = $liveSyncCommandHelper;
        this.$devicesService = $devicesService;
        this.$migrateController = $migrateController;
        this.platform = "android";
    }
    execute(args) {
        const _super = Object.create(null, {
            execute: { get: () => super.execute }
        });
        return __awaiter(this, void 0, void 0, function* () {
            yield _super.execute.call(this, args);
        });
    }
    canExecute(args) {
        const _super = Object.create(null, {
            canExecute: { get: () => super.canExecute }
        });
        return __awaiter(this, void 0, void 0, function* () {
            const canExecuteBase = yield _super.canExecute.call(this, args);
            if (canExecuteBase) {
                if ((this.$options.release || this.$options.aab) &&
                    !(0, helpers_1.hasValidAndroidSigning)(this.$options)) {
                    if (this.$options.release) {
                        this.$errors.failWithHelp(constants_1.ANDROID_RELEASE_BUILD_ERROR_MESSAGE);
                    }
                    else {
                        this.$errors.failWithHelp(constants_1.ANDROID_APP_BUNDLE_SIGNING_ERROR_MESSAGE);
                    }
                }
            }
            return canExecuteBase;
        });
    }
}
class TestIosCommand extends TestCommandBase {
    constructor($projectData, $testExecutionService, $analyticsService, $options, $platformEnvironmentRequirements, $errors, $cleanupService, $liveSyncCommandHelper, $devicesService, $migrateController) {
        super();
        this.$projectData = $projectData;
        this.$testExecutionService = $testExecutionService;
        this.$analyticsService = $analyticsService;
        this.$options = $options;
        this.$platformEnvironmentRequirements = $platformEnvironmentRequirements;
        this.$errors = $errors;
        this.$cleanupService = $cleanupService;
        this.$liveSyncCommandHelper = $liveSyncCommandHelper;
        this.$devicesService = $devicesService;
        this.$migrateController = $migrateController;
        this.platform = "iOS";
    }
}
yok_1.injector.registerCommand("test|android", TestAndroidCommand);
yok_1.injector.registerCommand("test|ios", TestIosCommand);
