"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.readRunResultsDirToMap = exports.intersectRunnerAndRootCause = exports.prepareRunConclusion = exports.readRunConclusion = exports.writeRunConclusion = exports.writeRunsHistory = exports.updateRunsHistory = exports.readRunsHistory = exports.concludeRun = void 0;
const fs_extra_1 = __importDefault(require("fs-extra"));
const p_map_1 = __importDefault(require("p-map"));
const p_filter_1 = __importDefault(require("p-filter"));
const path_1 = __importDefault(require("path"));
const consts_1 = require("../consts");
async function concludeRun(runId, rootCausePath, timestamp, finalResults) {
    const conclusion = prepareRunConclusion(runId, timestamp, finalResults);
    await writeRunConclusion(rootCausePath, runId, conclusion);
    const history = await readRunsHistory(rootCausePath);
    updateRunsHistory(history, conclusion, consts_1.HISTORY_RUNS_TO_RETAIN);
    await writeRunsHistory(rootCausePath, history);
}
exports.concludeRun = concludeRun;
async function readRunsHistory(rootCauseDirPath) {
    try {
        return JSON.parse(await fs_extra_1.default.readFile(path_1.default.resolve(rootCauseDirPath, consts_1.HISTORY_FILE_NAME), 'utf8'));
    }
    catch (e) {
        return [];
    }
}
exports.readRunsHistory = readRunsHistory;
function updateRunsHistory(history, conclusion, historyToKeep) {
    const runIdAlreadyInUse = history.findIndex((h) => h.runId === conclusion.runId);
    if (runIdAlreadyInUse > -1) {
        history.splice(runIdAlreadyInUse, 1);
    }
    history.unshift({
        runId: conclusion.runId,
        timestamp: conclusion.timestamp,
    });
    history.splice(historyToKeep);
}
exports.updateRunsHistory = updateRunsHistory;
async function writeRunsHistory(rootCauseDirPath, history) {
    return fs_extra_1.default.writeFile(path_1.default.resolve(rootCauseDirPath, consts_1.HISTORY_FILE_NAME), JSON.stringify(history, null, 2));
}
exports.writeRunsHistory = writeRunsHistory;
async function writeRunConclusion(rootCauseDirPath, runId, conclusion) {
    return fs_extra_1.default.writeFile(path_1.default.resolve(rootCauseDirPath, consts_1.RUNS_DIR_NAME, runId, consts_1.RUN_CONCLUSION_FILE_NAME), JSON.stringify(conclusion, null, 2));
}
exports.writeRunConclusion = writeRunConclusion;
async function readRunConclusion(rootCauseDirPath, runId) {
    return JSON.parse(await fs_extra_1.default.readFile(path_1.default.resolve(rootCauseDirPath, consts_1.RUNS_DIR_NAME, runId, consts_1.RUN_CONCLUSION_FILE_NAME), 'utf8'));
}
exports.readRunConclusion = readRunConclusion;
function prepareRunConclusion(runId, timestamp, data) {
    const conclusion = {
        runId,
        timestamp,
        tests: [...data].map(([id, entry]) => {
            var _a, _b, _c;
            return ({
                id,
                suiteFilePath: entry.runner.suiteFilePath,
                name: entry.runner.testResult.title,
                fullName: entry.runner.testResult.fullName,
                success: entry.runner.testResult.status === 'passed',
                timestamp: entry.rootCause.testData.metadata.timestamp,
                endedTimestamp: entry.rootCause.testData.metadata.endedTimestamp,
                reason: ((_a = entry.rootCause.testData.metadata.testEndStatus) === null || _a === void 0 ? void 0 : _a.success) === false
                    ? (_c = (_b = entry.rootCause.testData.metadata.testEndStatus) === null || _b === void 0 ? void 0 : _b.error) === null || _c === void 0 ? void 0 : _c.message : undefined,
            });
        }),
    };
    return conclusion;
}
exports.prepareRunConclusion = prepareRunConclusion;
function intersectRunnerAndRootCause(rootCauseSide, runnerSide) {
    const finalMap = new Map();
    for (const [testId, rootCauseEntry] of rootCauseSide) {
        const runnerEntry = runnerSide.get(testId);
        if (rootCauseEntry &&
            runnerEntry &&
            (runnerEntry.testResult.status === 'passed' || runnerEntry.testResult.status === 'failed')) {
            finalMap.set(testId, {
                runner: runnerEntry,
                rootCause: rootCauseEntry,
            });
        }
    }
    return finalMap;
}
exports.intersectRunnerAndRootCause = intersectRunnerAndRootCause;
async function readRunResultsDirToMap(inputDir) {
    if (!(await fs_extra_1.default.pathExists(inputDir))) {
        return new Map();
    }
    const resultsDirsList = await p_filter_1.default(await fs_extra_1.default.readdir(inputDir), async (maybeDirPath) => {
        if (!(await fs_extra_1.default.stat(path_1.default.resolve(inputDir, maybeDirPath))).isDirectory()) {
            return false;
        }
        return fs_extra_1.default.pathExists(path_1.default.resolve(inputDir, maybeDirPath, consts_1.TEST_RESULTS_FILE_NAME));
    }, { concurrency: 4 });
    const resultsList = await Promise.all(await p_map_1.default(resultsDirsList, async (singleResultDirName) => {
        const singleResultDir = path_1.default.resolve(inputDir, singleResultDirName);
        const singleResultFile = path_1.default.resolve(singleResultDir, consts_1.TEST_RESULTS_FILE_NAME);
        const testData = JSON.parse(await fs_extra_1.default.readFile(singleResultFile, 'utf8'));
        const id = singleResultDirName;
        return {
            singleResultDir,
            id,
            testData,
        };
    }, { concurrency: 4 }));
    return new Map(resultsList.map((e) => [e.id, e]));
}
exports.readRunResultsDirToMap = readRunResultsDirToMap;
