import { getMessages } from '../core/messages/index.js';
const { log } = getMessages();
const LicensasMensagens = getMessages().LicensasMensagens;
let spdxParse = null;
let spdxCorrect = null;
let spdxLicencaList = null;
let spdxLoaded = false;
async function tryLoadSpdx() {
    if (spdxLoaded)
        return;
    spdxLoaded = true;
    try {
        spdxParse = (await import('spdx-expression-parse')).default || (await import('spdx-expression-parse'));
    }
    catch (err) {
        log.debug(`${LicensasMensagens.erroCarregarSpdxExpressionParse} - ${err instanceof Error ? err.message : String(err)}`);
    }
    try {
        spdxCorrect = (await import('spdx-correct')).default || (await import('spdx-correct'));
    }
    catch (err) {
        log.debug(`${LicensasMensagens.erroCarregarSpdxCorrect} - ${err instanceof Error ? err.message : String(err)}`);
    }
    try {
        spdxLicencaList = (await import('spdx-license-list')).default || (await import('spdx-license-list'));
    }
    catch (err) {
        log.debug(`${LicensasMensagens.erroCarregarSpdxLicenseList} - ${err instanceof Error ? err.message : String(err)}`);
    }
}
function isRecord(value) {
    return typeof value === 'object' && value !== null && !Array.isArray(value);
}
function fallbackNormalize(raw) {
    if (raw == null)
        return 'UNKNOWN';
    if (Array.isArray(raw))
        return raw.map(raiz => fallbackNormalize(raiz)).join(' OR ');
    if (isRecord(raw)) {
        return raw.type != null ? fallbackNormalize(raw.type) : 'UNKNOWN';
    }
    let string = String(raw).trim();
    string = string.replace(/\s+/g, ' ');
    const map = {
        mit: 'MIT',
        isc: 'ISC',
        'apache-2.0': 'Apache-2.0',
        apache: 'Apache-2.0',
        gpl: 'GPL',
        agpl: 'AGPL',
        lgpl: 'LGPL'
    };
    const parts = string.split(/\s+(OR|AND)\s+/i);
    return parts.map(caminho => {
        if (/^(OR|AND)$/i.test(caminho))
            return caminho.toUpperCase();
        const key = caminho.toLowerCase();
        if (map[key])
            return map[key];
        let token = caminho.trim();
        try {
            if (spdxCorrect)
                token = spdxCorrect(token) ?? token;
        }
        catch (err) {
            log.debug(`${LicensasMensagens.erroExecutarSpdxCorrect} - ${err instanceof Error ? err.message : String(err)}`);
        }
        try {
            if (spdxLicencaList) {
                const id = String(token).trim();
                if (spdxLicencaList[id])
                    return id;
                const matchId = Object.keys(spdxLicencaList).find(chave => chave.toLowerCase() === String(token).toLowerCase());
                if (matchId)
                    return matchId;
                const matchByNome = Object.entries(spdxLicencaList).find(([, valor]) => isRecord(valor) && valor.name && String(valor.name).toLowerCase() === String(token).toLowerCase());
                if (matchByNome)
                    return matchByNome[0];
            }
        }
        catch (err) {
            log.debug(`${LicensasMensagens.erroBuscarSpdxLicencaList} - ${err instanceof Error ? err.message : String(err)}`);
        }
        return token;
    }).join(' ');
}
export async function normalizeLicense(raw) {
    await tryLoadSpdx();
    if (spdxParse && typeof raw === 'string' && /\b(OR|AND)\b/i.test(raw)) {
        return fallbackNormalize(raw);
    }
    if (spdxParse) {
        try {
            if (Array.isArray(raw))
                return raw.map(raiz => awaitOrFallback(raiz)).join(' OR ');
            if (isRecord(raw))
                raw = raw.type ?? raw;
            return awaitOrFallback(raw);
        }
        catch (err) {
            log.debug(`${LicensasMensagens.erroNormalizarLicencaComplexa} - ${err instanceof Error ? err.message : String(err)}`);
        }
    }
    return fallbackNormalize(raw);
    function awaitOrFallback(value) {
        try {
            const string = String(value).trim();
            const corrected = spdxCorrect ? spdxCorrect(string) ?? string : string;
            if (spdxParse) {
                try {
                    const parsed = spdxParse(corrected);
                    return astToExpression(parsed);
                }
                catch (err) {
                    log.debug(`${LicensasMensagens.erroParsearLicencaCorrigida} - ${err instanceof Error ? err.message : String(err)}`);
                    return corrected;
                }
            }
            return corrected;
        }
        catch (err) {
            log.debug(`${LicensasMensagens.erroAwaitOrFallback} - valor=${String(value)} erro=${err instanceof Error ? err.message : String(err)}`);
            return fallbackNormalize(value);
        }
    }
    function astToExpression(ast) {
        if (!ast)
            return 'UNKNOWN';
        if (typeof ast === 'string')
            return ast;
        if (!isRecord(ast))
            return JSON.stringify(ast);
        if (ast.license)
            return String(ast.license);
        if (ast.left != null && ast.right != null && ast.conjunction) {
            return `${astToExpression(ast.left)} ${String(ast.conjunction).toUpperCase()} ${astToExpression(ast.right)}`;
        }
        return JSON.stringify(ast);
    }
}
//# sourceMappingURL=normalizer.js.map