"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const assertion_error_diff_1 = require("assertion-error-diff");
const typed_colors_1 = require("typed-colors");
const typed_figures_1 = require("typed-figures");
const collectByKey_1 = require("../common/collectByKey");
function resultsToString(results) {
    const resultsByFilePath = collectByKey_1.collectByKey(x => x.filePath, results);
    const filePaths = Object.keys(resultsByFilePath).sort();
    let str = `\n`;
    const lastIndex = filePaths.length - 1;
    filePaths.forEach((filePath, index) => {
        const jsonResults = resultsByFilePath[filePath];
        if (index !== 0) {
            str += `\n`;
        }
        str += typed_colors_1.underline(filePath);
        for (const jsonResult of jsonResults) {
            str +=
                `\n` +
                    moveIn(jsonResult.results
                        .map(result => resultToString(filePath + `:${jsonResult.line}`, result))
                        .join(`\n`));
        }
        if (index !== lastIndex) {
            str += `\n`;
        }
    });
    return str.replace(/\n(\s)+\n(\s)+\n/g, '\n\n');
}
exports.resultsToString = resultsToString;
function resultToString(filePath, result, nested = false) {
    if (result.type === 'pass') {
        return formatPassingResult(result, nested);
    }
    if (result.type === 'fail') {
        return formatFailingResult(filePath, result, nested);
    }
    if (result.type === 'skip') {
        return formatSkippedResult(result, nested);
    }
    return formatGroupResult(filePath, result);
}
exports.resultToString = resultToString;
function testName(name) {
    const itRegex = /^it\s/;
    const givenRegex = /^given\s/;
    if (itRegex.test(name)) {
        return name.replace(itRegex, `${typed_colors_1.blue('it ')}`);
    }
    if (givenRegex.test(name)) {
        return name.replace(givenRegex, `${typed_colors_1.blue('given ')}`);
    }
    return name;
}
function formatPassingResult({ name }, nested) {
    return newLineWhenNotNested(`${typed_colors_1.green(typed_figures_1.tick)} ${testName(name)}`, nested);
}
function formatFailingResult(filePath, { name, error }, nested) {
    const resultName = `${typed_colors_1.red(typed_figures_1.cross)} ${testName(name)} - ${filePath}`;
    try {
        const resultError = assertion_error_diff_1.errorToString(error);
        return newLineWhenNotNested(resultName + moveIn(`\n` + resultError), nested);
    }
    catch (_a) {
        const errorMessage = error.stack ? error.stack : error.message;
        return newLineWhenNotNested(resultName + moveIn(`\n` + errorMessage), nested);
    }
}
function formatSkippedResult({ name }, nested) {
    return newLineWhenNotNested(`${typed_colors_1.blue('(Skipped)')} ${testName(name)}`, nested);
}
function formatGroupResult(filePath, result) {
    const { results, name } = result;
    return (`\n${typed_colors_1.underline(typed_colors_1.bold(testName(name)))}\n  ` +
        moveIn(results
            .map((x, i) => {
            const r = resultToString(filePath, x, true);
            if (i > 0 && x.type !== 'group' && results[i - 1].type === 'group') {
                return `\n${r}`;
            }
            return x.type === 'fail' ? `${r}\n` : r;
        })
            .join(`\n`)));
}
function newLineWhenNotNested(s, nested) {
    return nested ? s : `\n${s}`;
}
function moveIn(str) {
    return str.replace(/\n/g, `\n  `);
}
//# sourceMappingURL=resultToString.js.map