"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateMochAwesomeReportFromTestResults = generateMochAwesomeReportFromTestResults;
exports.generatePlainSuiteFromTestResults = generatePlainSuiteFromTestResults;
exports.generateReportOptions = generateReportOptions;
const uuid_1 = require("uuid");
const TestResult_1 = require("../../core/execution/TestResult");
const mochawesome_report_generator_1 = __importDefault(require("mochawesome-report-generator"));
const moment_1 = __importDefault(require("moment"));
const loggingProvider_1 = require("../../providers/logging/loggingProvider");
const path = __importStar(require("path"));
const pureUtil_1 = require("../../util/pureUtil");
function generateMochAwesomeReportFromTestResults(testResults, reportOptions) {
    const plainSuite = generatePlainSuiteFromTestResults(testResults);
    const parentSuite = generateHoldingTestSuiteObj(plainSuite);
    const finalOptions = generateReportOptions(reportOptions);
    const cliVersion = `@mablhq/mabl-cli@${(0, pureUtil_1.getCliVersion)()}`;
    const testReportObj = {
        results: [parentSuite],
        stats: {
            testsRegistered: testResults.numTotalTests,
            passPercent: (testResults.numPassedTests /
                (testResults.numTotalTests - testResults.numSkippedTests)) *
                100,
            pendingPercent: 0,
            other: 0,
            hasOther: false,
            skipped: testResults.numSkippedTests,
            hasSkipped: !!testResults.numSkippedTests,
            start: (0, moment_1.default)(testResults.startTime).toISOString(),
            end: (0, moment_1.default)(testResults.endTime).toISOString(),
            duration: testResults.endTime - testResults.startTime,
            failures: testResults.numFailedTests,
            passes: testResults.numPassedTests,
            pending: 0,
            suites: 1,
            tests: testResults.numTotalTests,
        },
        meta: {
            mocha: {
                version: cliVersion,
            },
            mochawesome: {
                options: 'unavailable',
                version: cliVersion,
            },
            marge: {
                options: finalOptions,
                version: cliVersion,
            },
        },
    };
    const input = finalOptions.saveHtml
        ? JSON.stringify(testReportObj)
        : testReportObj;
    return mochawesome_report_generator_1.default
        .create(input, finalOptions)
        .then(([_, file]) => {
        loggingProvider_1.logger.info(`Report generated: ${file}`);
    })
        .catch((error) => {
        loggingProvider_1.logger.error(error);
    });
}
function generatePlainSuiteFromTestResults(testResults) {
    const parentId = (0, uuid_1.v4)();
    const plainTests = testResults.testResults.map((testResult) => generatePlainTestForTestRun(parentId, testResult));
    const passes = plainTests
        .filter((test) => test.pass)
        .map((test) => test.uuid);
    const failures = plainTests
        .filter((test) => test.fail)
        .map((test) => test.uuid);
    const skipped = plainTests
        .filter((test) => test.skipped)
        .map((test) => test.uuid);
    const command = constructTestRunCommand();
    return {
        uuid: parentId,
        title: command ?? `mabl CLI tests`,
        fullFile: '',
        file: '',
        beforeHooks: [],
        afterHooks: [],
        tests: plainTests,
        suites: [],
        passes,
        failures,
        pending: [],
        skipped,
        duration: testResults.totalTimeSeconds * 1000,
        root: true,
        rootEmpty: false,
        _timeout: 0,
    };
}
function generatePlainTestForTestRun(parentUuid, testResult) {
    return {
        title: testResult.testName ?? '',
        fullTitle: `${testResult.testName} - ${testResult.testId}`,
        timedOut: false,
        code: getCodeForResult(testResult),
        pass: testResult.status === TestResult_1.TestResultStatus.passed,
        fail: testResult.status === TestResult_1.TestResultStatus.failed,
        pending: false,
        uuid: (0, uuid_1.v4)(),
        isHook: false,
        skipped: testResult.status === TestResult_1.TestResultStatus.skipped,
        err: testResult.errorMessage
            ? {
                message: testResult.errorMessage,
            }
            : {},
        duration: testResult.endTime - testResult.startTime,
        parentUUID: parentUuid,
        state: getTestState(testResult.status),
    };
}
function getCodeForResult(testResult) {
    switch (testResult.status) {
        case TestResult_1.TestResultStatus.passed:
            return 'Test passed';
        case TestResult_1.TestResultStatus.skipped:
            return 'Test was skipped';
        case TestResult_1.TestResultStatus.failed:
            return 'Test has failed';
        default:
            return '';
    }
}
function getTestState(testResultStatus) {
    switch (testResultStatus) {
        case TestResult_1.TestResultStatus.passed:
            return 'passed';
        case TestResult_1.TestResultStatus.failed:
            return 'failed';
        default:
            return;
    }
}
function constructTestRunCommand() {
    try {
        const processArgs = process.argv;
        const testArgIndex = processArgs.findIndex((arg) => arg === 'tests');
        if (testArgIndex) {
            processArgs.splice(0, testArgIndex + 1);
        }
        return `mabl ${processArgs.join(' ')}`;
    }
    catch (error) {
        loggingProvider_1.logger.debug('Could not create original command for report');
    }
    return;
}
function generateHoldingTestSuiteObj(suite) {
    return {
        uuid: (0, uuid_1.v4)(),
        title: `mabl CLI test run`,
        fullFile: 'mabl/tests/run',
        file: 'mabl/tests/run',
        beforeHooks: [],
        afterHooks: [],
        tests: [],
        suites: [suite],
        passes: [],
        failures: [],
        pending: [],
        skipped: [],
        duration: 0,
        root: true,
        rootEmpty: true,
        _timeout: 0,
    };
}
function generateReportOptions(supplied) {
    if (supplied.json) {
        supplied.saveJson = supplied.json;
        supplied.saveHtml = !supplied.saveJson;
    }
    else if (supplied.html) {
        supplied.saveHtml = supplied.html;
        supplied.saveJson = !supplied.saveHtml;
    }
    return {
        reportFilename: supplied.reportFilename ?? `mabl-mochawesomeReport`,
        reportDir: supplied.reportDir ?? path.normalize(`./mablReports`),
        overwrite: supplied.overwrite ?? true,
        reportTitle: supplied.reportTitle ?? `mabl mochawesome report`,
        reportPageTitle: supplied.reportPageTitle ?? `mabl mochawesome report`,
        autoOpen: supplied.autoOpen ?? !supplied.saveJson,
        showPassed: supplied.showPassed ?? true,
        showFailed: supplied.showFailed ?? true,
        showPending: supplied.showPending ?? true,
        showSkipped: supplied.showSkipped ?? true,
        saveJson: supplied.saveJson,
        saveHtml: supplied.saveHtml,
    };
}
