"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateError = void 0;
const type_1 = require("./type");
const source_map_1 = require("source-map");
const utils_1 = require("@modern-js/utils");
const utils_2 = require("./utils");
async function generateError({ err, filepath, code, exclude, }) {
    let error = await tryGenerateErrorFromSourceMap(err, filepath);
    if (!error) {
        const SUB_LEN = 25;
        const path = filepath.replace(process.cwd(), '');
        error = new type_1.SyntaxError(err.message, {
            source: {
                path,
                line: err.loc.line,
                column: err.loc.column,
                code: code.substring(err.pos - SUB_LEN, err.pos + SUB_LEN).trim(),
            },
        });
    }
    if ((0, utils_2.checkIsExcludeSource)(error.source.path, exclude)) {
        return null;
    }
    return error;
}
exports.generateError = generateError;
async function tryGenerateErrorFromSourceMap(err, filepath) {
    var _a, _b, _c, _d, _e;
    const sourceMapPath = `${filepath}.map`;
    if (!utils_1.fs.existsSync(sourceMapPath)) {
        return null;
    }
    try {
        const sourcemap = await utils_1.fs.readFile(sourceMapPath, 'utf-8');
        const consumer = await new source_map_1.SourceMapConsumer(sourcemap);
        const sm = consumer.originalPositionFor({
            line: err.loc.line,
            column: err.loc.column,
        });
        if (!sm.source) {
            return null;
        }
        const { sources } = consumer;
        const smIndex = sources.indexOf(sm.source);
        const smContent = (_b = (_a = JSON.parse(sourcemap)) === null || _a === void 0 ? void 0 : _a.sourcesContent) === null || _b === void 0 ? void 0 : _b[smIndex];
        if (!smContent) {
            return null;
        }
        const path = sm.source.replace('webpack://', '');
        const rawLines = smContent.split(/\r?\n/g);
        return new type_1.SyntaxError(err.message, {
            source: {
                path,
                line: (_c = sm.line) !== null && _c !== void 0 ? _c : 0,
                column: (_d = sm.column) !== null && _d !== void 0 ? _d : 0,
                code: rawLines[((_e = sm.line) !== null && _e !== void 0 ? _e : 0) - 1].trim(),
            },
            output: {
                path: filepath,
                line: err.loc.line,
                column: err.loc.column,
            },
        });
    }
    catch (e) {
        return null;
    }
}
