"use strict";
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 },
        };
    }
    async execute(args) {
        let devices = [];
        if (this.$options.debugBrk) {
            await this.$devicesService.initialize({
                platform: this.platform,
                deviceId: this.$options.device,
                emulator: this.$options.emulator,
                skipInferPlatform: !this.platform,
                sdk: this.$options.sdk,
            });
            const selectedDeviceForDebug = await this.$devicesService.pickSingleDevice({
                onlyEmulators: this.$options.emulator,
                onlyDevices: this.$options.forDevice,
                deviceId: this.$options.device,
            });
            devices = [selectedDeviceForDebug];
        }
        else {
            devices = await 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 = await this.$liveSyncCommandHelper.createDeviceDescriptors(devices, this.platform, { deviceDebugMap });
        await this.$testExecutionService.startKarmaServer(this.platform, liveSyncInfo, deviceDescriptors);
        process.exit(0);
    }
    async canExecute(args) {
        if (!this.$options.force) {
            if (this.$options.hmr) {
                this.$errors.fail("The `--hmr` option is not supported for this command.");
            }
            await 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 = await this.$platformEnvironmentRequirements.checkEnvironmentRequirements({
            platform: this.platform,
            projectDir: this.$projectData.projectDir,
            options: this.$options,
        });
        const canStartKarmaServer = await 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";
    }
    async execute(args) {
        await super.execute(args);
    }
    async canExecute(args) {
        const canExecuteBase = await super.canExecute(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);
