"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 results_1 = require("../../results");
const constants_1 = require("../constants");
// tslint:disable-next-line:no-var-requires
const { mapStackTrace } = require('sourcemapped-stacktrace');
function reportResults(results, cwd) {
    const rootElement = document.getElementById(constants_1.ROOT_ELEMENT_ID);
    if (rootElement) {
        clearChildren(rootElement);
        addResults(rootElement, results_1.getTestResults(results));
    }
    return sendResultsToServer(results, cwd);
}
exports.reportResults = reportResults;
function clearChildren(rootElement) {
    const { childNodes } = rootElement;
    const childCount = childNodes.length;
    for (let i = 0; i < childCount; ++i) {
        rootElement.removeChild(childNodes[i]);
    }
    return rootElement;
}
function addResults(rootElement, results) {
    rootElement.appendChild(results_1.resultsToDom(results));
    return rootElement;
}
function sendResultsToServer(results, cwd) {
    return __awaiter(this, void 0, void 0, function* () {
        const jsonReadyResults = yield prepareTestResults(results, cwd);
        yield fetch(`/results`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(jsonReadyResults),
        });
    });
}
function prepareTestResults(results, cwd) {
    return __awaiter(this, void 0, void 0, function* () {
        const jsonReadyResults = [];
        for (const result of results) {
            jsonReadyResults.push(Object.assign({}, result, { results: yield prepareResults(result.results, cwd) }));
        }
        return jsonReadyResults;
    });
}
function prepareResults(results, cwd) {
    return __awaiter(this, void 0, void 0, function* () {
        const jsonReadyResults = [];
        for (const result of results) {
            jsonReadyResults.push(yield prepareResult(result, cwd));
        }
        return jsonReadyResults;
    });
}
function prepareResult(result, cwd) {
    return __awaiter(this, void 0, void 0, function* () {
        switch (result.type) {
            case 'pass':
            case 'skip':
                return result;
            case 'fail': {
                const error = yield prepareError(result.error, cwd);
                return Object.assign({}, result, { error });
            }
        }
        const results = yield prepareResults(result.results, cwd);
        return Object.assign({}, result, { results });
    });
}
function prepareError(error, cwd) {
    return __awaiter(this, void 0, void 0, function* () {
        return Object.assign({ message: error.message, stack: error.stack && (yield sourceMapStack(error.stack, cwd)) }, error);
    });
}
function sourceMapStack(stack, cwd) {
    return __awaiter(this, void 0, void 0, function* () {
        return new Promise(resolve => {
            mapStackTrace(stack, (trace) => resolve(trace.join(`\n`).replace(/webpack:\/\/TypedTest/g, cwd)));
        });
    });
}
//# sourceMappingURL=reportResults.js.map