import ts from "typescript";
import { fsx } from "@simplysm/core-node";
function serializeMessageChain(chain) {
    return {
        messageText: chain.messageText,
        category: chain.category,
        code: chain.code,
        next: chain.next?.map(serializeMessageChain),
    };
}
function serializeMessageText(messageText) {
    if (typeof messageText === "string")
        return messageText;
    return serializeMessageChain(messageText);
}
/**
 * Diagnostic을 직렬화 가능한 형태로 변환한다.
 * (Worker 스레드 간 structured clone 통신을 위해 순환 참조/함수를 제거)
 * messageText chain, relatedInformation, reportsUnnecessary/Deprecated, source 등 모든 detail 보존.
 */
export function serializeDiagnostic(diagnostic) {
    return {
        category: diagnostic.category,
        code: diagnostic.code,
        messageText: serializeMessageText(diagnostic.messageText),
        file: diagnostic.file != null ? { fileName: diagnostic.file.fileName } : undefined,
        start: diagnostic.start,
        length: diagnostic.length,
        relatedInformation: diagnostic.relatedInformation?.map((ri) => ({
            category: ri.category,
            code: ri.code,
            messageText: serializeMessageText(ri.messageText),
            file: ri.file != null ? { fileName: ri.file.fileName } : undefined,
            start: ri.start,
            length: ri.length,
        })),
        reportsUnnecessary: diagnostic.reportsUnnecessary != null ? true : undefined,
        reportsDeprecated: diagnostic.reportsDeprecated != null ? true : undefined,
        source: diagnostic.source,
    };
}
/**
 * 파일명에서 TypeScript ScriptKind를 결정한다.
 */
function getScriptKind(fileName) {
    if (fileName.endsWith(".js") || fileName.endsWith(".mjs") || fileName.endsWith(".cjs"))
        return ts.ScriptKind.JS;
    return ts.ScriptKind.TS;
}
/**
 * SerializedDiagnostic을 ts.Diagnostic으로 복원한다.
 * formatDiagnosticsWithColorAndContext에서 소스 코드 컨텍스트가 표시되도록 실제 파일 내용을 읽는다.
 * @param serialized - 직렬화된 진단 정보
 * @param fileCache - 파일 내용 캐시 (같은 파일의 중복 읽기 방지)
 * @returns 복원된 ts.Diagnostic 객체
 */
function deserializeMessageChain(chain) {
    return {
        messageText: chain.messageText,
        category: chain.category,
        code: chain.code,
        next: chain.next?.map(deserializeMessageChain),
    };
}
function deserializeMessageText(messageText) {
    if (typeof messageText === "string")
        return messageText;
    return deserializeMessageChain(messageText);
}
function loadFile(fileName, fileCache) {
    if (!fileCache.has(fileName)) {
        fileCache.set(fileName, fsx.existsSync(fileName) ? fsx.readSync(fileName) : "");
    }
    const content = fileCache.get(fileName);
    const scriptKind = getScriptKind(fileName);
    return ts.createSourceFile(fileName, content, ts.ScriptTarget.Latest, false, scriptKind);
}
export function deserializeDiagnostic(serialized, fileCache) {
    const file = serialized.file != null ? loadFile(serialized.file.fileName, fileCache) : undefined;
    const relatedInformation = serialized.relatedInformation?.map((ri) => ({
        category: ri.category,
        code: ri.code,
        messageText: deserializeMessageText(ri.messageText),
        file: ri.file != null ? loadFile(ri.file.fileName, fileCache) : undefined,
        start: ri.start,
        length: ri.length,
    }));
    return {
        category: serialized.category,
        code: serialized.code,
        messageText: deserializeMessageText(serialized.messageText),
        file,
        start: serialized.start,
        length: serialized.length,
        relatedInformation,
        reportsUnnecessary: serialized.reportsUnnecessary === true ? {} : undefined,
        reportsDeprecated: serialized.reportsDeprecated === true ? {} : undefined,
        source: serialized.source,
    };
}
//# sourceMappingURL=typecheck-serialization.js.map