"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());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const watchTestMetadata_1 = require("../tests/watchTestMetadata");
const findTsConfig_1 = require("../typescript/findTsConfig");
const findTypedTestConfigs_1 = require("./findTypedTestConfigs");
const log_1 = require("./log");
const TestRunner_1 = require("./TestRunner");
const watchBrowserTests_1 = require("./watchBrowserTests");
const findTestMetadata_1 = require("../tests/findTestMetadata");
const Results_1 = require("./Results");
const results_1 = require("../results");
const EXCLUDE = ['./node_modules/**'];
function runTypedTest(userOptions) {
    return __awaiter(this, void 0, void 0, function* () {
        const cwd = process.cwd();
        const { compilerOptions, files = [], include = [], exclude = EXCLUDE } = findTsConfig_1.findTsConfig(cwd);
        const fileGlobs = [...files, ...include, ...exclude.map(x => `!${x}`)];
        const typedTestConfigs = findTypedTestConfigs_1.findTypedTestConfigs(compilerOptions, cwd);
        const results = new Results_1.Results();
        const hasWatch = typedTestConfigs.some(x => !!x.watch) || (!!userOptions && !!userOptions.watch);
        const disposables = yield Promise.all(typedTestConfigs.map(typedTestConfig => run(Object.assign({}, typedTestConfig, userOptions), cwd, fileGlobs, compilerOptions, results, hasWatch)));
        if (!hasWatch) {
            const stats = results_1.getTestStats(results_1.getTestResults(results.getResults()));
            const exitCode = stats.failing > 0 ? 1 : 0;
            process.exit(exitCode);
        }
        return disposables;
    });
}
exports.runTypedTest = runTypedTest;
function run(userOptions, cwd, fileGlobs, compilerOptions, globalResults, useGlobalResults) {
    return __awaiter(this, void 0, void 0, function* () {
        const { options, results: { removeFilePath }, runTests, logger, } = new TestRunner_1.TestRunner(userOptions, useGlobalResults ? globalResults : null, cwd);
        const { updateResults } = globalResults;
        const { mode, watch, files: userFiles } = options;
        const fileGlobsToUse = userFiles.length > 0 ? userFiles : fileGlobs;
        if (mode == 'browser' && watch) {
            return watchBrowserTests_1.watchBrowserTests(fileGlobsToUse, compilerOptions, options, cwd, logger, ({ results }) => {
                updateResults(results);
                log_1.logResults(logger, results);
            }, console.error, results => log_1.logTypeCheckResults(logger, results));
        }
        const handleMetadata = (metadata) => __awaiter(this, void 0, void 0, function* () {
            const [{ results }, processResults] = yield runTests(metadata);
            updateResults(results);
            log_1.logTypeCheckResults(logger, processResults);
            log_1.logResults(logger, results);
        });
        if (watch) {
            return watchTestMetadata_1.watchTestMetadata(cwd, fileGlobsToUse, compilerOptions, mode, logger, removeFilePath, handleMetadata);
        }
        const metadata = yield findTestMetadata_1.findTestMetadata(cwd, fileGlobsToUse, compilerOptions, mode);
        yield handleMetadata(metadata);
        return { dispose: () => { } };
    });
}
//# sourceMappingURL=runTypedTest.js.map