import chalk from "chalk";
class LogRecorder {
    #currentTestLogMessages = [];
    #isTestFailed = false;
    addLog(msg) {
        this.#currentTestLogMessages.push(msg);
    }
    markTestFailed() {
        this.#isTestFailed = true;
    }
    reset() {
        this.#currentTestLogMessages = [];
        this.#isTestFailed = false;
    }
    onFinishTest() {
        if (this.#currentTestLogMessages.length === 0) {
            return null;
        }
        if (this.#isTestFailed === false) {
            return null;
        }
        return this.#currentTestLogMessages;
    }
}
export class ExecutionResult {
    total = 0;
    fail = 0;
    failedInfo = {};
    crashInfo = new Set();
    failedLogMessages = {};
}
export class ExecutionRecorder {
    result = new ExecutionResult();
    registerFunctions = [];
    #currentTestDescriptions = [];
    #testCaseFullName = "";
    logRecorder = new LogRecorder();
    set testCaseFullName(testCaseFullName) {
        this.#testCaseFullName = testCaseFullName;
    }
    _addDescription(description) {
        this.#currentTestDescriptions.push(description);
    }
    _removeDescription() {
        this.#currentTestDescriptions.pop();
    }
    _registerTestFunction(fncIndex) {
        const testCaseFullName = this.#currentTestDescriptions.join(" ");
        this.registerFunctions.push([testCaseFullName, fncIndex]);
    }
    startTestFunction(testCaseFullName) {
        this.#testCaseFullName = testCaseFullName;
        this.logRecorder.reset();
    }
    finishTestFunction() {
        const logMessages = this.logRecorder.onFinishTest();
        if (logMessages !== null) {
            this.result.failedLogMessages[this.#testCaseFullName] = (this.result.failedLogMessages[this.#testCaseFullName] || []).concat(logMessages);
        }
    }
    notifyTestCrash(error) {
        this.logRecorder.addLog(`Reason: ${chalk.red(error.message)}`);
        this.logRecorder.addLog(error.stacks
            .map((stack) => `  at ${stack.functionName} (${stack.fileName}:${stack.lineNumber}:${stack.columnNumber})`)
            .join("\n"));
        this.result.crashInfo.add(this.#testCaseFullName);
        this.result.total++; // fake test cases
        this.#increaseFailureCount();
    }
    collectCheckResult(result, codeInfoIndex, actualValue, expectValue) {
        this.result.total++;
        if (!result) {
            this.#increaseFailureCount();
            const testCaseFullName = this.#testCaseFullName;
            const assertMessage = [codeInfoIndex.toString(), actualValue, expectValue];
            this.result.failedInfo[testCaseFullName] = this.result.failedInfo[testCaseFullName] || [];
            this.result.failedInfo[testCaseFullName].push(assertMessage);
        }
    }
    log(msg) {
        this.logRecorder.addLog(msg);
    }
    getCollectionFuncSet(arg) {
        return {
            addDescription: (description) => {
                this._addDescription(arg.exports.__getString(description));
            },
            removeDescription: () => {
                this._removeDescription();
            },
            registerTestFunction: (index) => {
                this._registerTestFunction(index);
            },
            collectCheckResult: (result, codeInfoIndex, actualValue, expectValue) => {
                this.collectCheckResult(result !== 0, codeInfoIndex, arg.exports.__getString(actualValue), arg.exports.__getString(expectValue));
            },
        };
    }
    #increaseFailureCount() {
        this.result.fail++;
        this.logRecorder.markTestFailed();
    }
}
//# sourceMappingURL=executionRecorder.js.map