"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseUTSArkTSRuntimeStacktrace = exports.parseUTSHarmonyRuntimeStacktrace = exports.parseUTSArkTSPluginStacktrace = void 0;
const path_1 = require("path");
const shared_1 = require("../shared");
const sourceMap_1 = require("../sourceMap");
const utils_1 = require("./utils");
const fs_extra_1 = require("fs-extra");
const js_1 = require("./js");
const utils_2 = require("../utils");
const ARKTS_COMPILE_ERROR_RE = /File:\s+(.*):(\d+):(\d+)/;
// at test (uni_modules/test-error/utssdk/app-harmony/index.ets:2:11)
const ARKTS_RUNTIME_ERROR_RE = /at\s+(?:.*)\s+\((uni_modules\/.*?\.ets):(\d+):(\d+)\)/;
/**
 * 解析uts插件编译时的ArkTS的堆栈信息
 */
async function parseUTSArkTSPluginStacktrace(stacktrace, options) {
    return parseUTSArkTSStacktrace('compile', stacktrace, options, ARKTS_COMPILE_ERROR_RE);
}
exports.parseUTSArkTSPluginStacktrace = parseUTSArkTSPluginStacktrace;
async function parseUTSArkTSStacktrace(type, stacktrace, options, re) {
    const lines = stacktrace.split(utils_1.splitRE);
    const res = [];
    const errorMessageLines = [];
    let parsedError = false;
    for (let i = 0; i < lines.length; i++) {
        const line = lines[i];
        try {
            const codes = await parseUTSStacktraceLine(line, re, options);
            if (codes && codes.length) {
                parsedError = true;
                res.push(...codes);
                if (type === 'runtime') {
                    if (errorMessageLines.length) {
                        errorMessageLines[0] = 'error: ' + errorMessageLines[0];
                    }
                    break;
                }
            }
            else {
                errorMessageLines.push(line);
            }
        }
        catch (e) {
            errorMessageLines.push(line);
        }
    }
    if (res.length) {
        res.unshift(...errorMessageLines);
    }
    else {
        res.push(...errorMessageLines);
    }
    if (parsedError) {
        return (utils_2.SPECIAL_CHARS.ERROR_BLOCK + res.join('\n') + utils_2.SPECIAL_CHARS.ERROR_BLOCK);
    }
    return res.join('\n');
}
async function parseUTSStacktraceLine(lineStr, re, options) {
    const uniModulesMatches = lineStr.match(re);
    if (!uniModulesMatches) {
        return;
    }
    const lines = [];
    const [, etsFile, line, column] = uniModulesMatches;
    // 编译时获取到的是绝对路径
    const filename = (0, path_1.isAbsolute)(etsFile)
        ? etsFile
        : // 运行时获取到的是相对路径
            (0, path_1.join)(options.inputDir, etsFile);
    const parts = (0, shared_1.normalizePath)(filename).split('/uni_modules/');
    if (parts.length > 1) {
        const relativePath = 'uni_modules/' + parts[parts.length - 1];
        const srcFileName = (0, path_1.join)(options.inputDir, relativePath);
        if ((0, fs_extra_1.existsSync)(srcFileName)) {
            lines.push(`at ${relativePath}:${line}:${column}`);
            lines.push((0, utils_1.generateCodeFrame)((0, fs_extra_1.readFileSync)(srcFileName, 'utf-8'), {
                line: parseInt(line),
                column: parseInt(column),
            }).replace(/\t/g, ' '));
            return lines;
        }
    }
    const sourceMapFile = (0, sourceMap_1.resolveUTSPluginSourceMapFile)('arkts', filename, options.inputDir, options.outputDir);
    const originalPosition = await (0, sourceMap_1.originalPositionFor)({
        sourceMapFile,
        line: parseInt(line),
        column: parseInt(column),
        withSourceContent: true,
    });
    if (originalPosition.source && originalPosition.sourceContent) {
        lines.push(`at ${(0, utils_1.parseRelativeSourceFile)(originalPosition.source.split('?')[0], options.inputDir)}:${originalPosition.line}:${originalPosition.column}`);
        if (originalPosition.line !== null && originalPosition.column !== null) {
            lines.push((0, utils_1.generateCodeFrame)(originalPosition.sourceContent, {
                line: originalPosition.line,
                column: originalPosition.column,
            }).replace(/\t/g, ' '));
        }
    }
    else {
        lines.push(lineStr);
    }
    return lines;
}
function parseUTSHarmonyRuntimeStacktrace(stacktrace, options) {
    if (ARKTS_RUNTIME_ERROR_RE.test(stacktrace)) {
        return parseUTSArkTSRuntimeStacktrace(stacktrace, options);
    }
    return (0, js_1.parseUTSJavaScriptRuntimeStacktrace)(stacktrace, options);
}
exports.parseUTSHarmonyRuntimeStacktrace = parseUTSHarmonyRuntimeStacktrace;
function parseUTSArkTSRuntimeStacktrace(stacktrace, options) {
    return parseUTSArkTSStacktrace('runtime', stacktrace, options, ARKTS_RUNTIME_ERROR_RE);
}
exports.parseUTSArkTSRuntimeStacktrace = parseUTSArkTSRuntimeStacktrace;
