"use strict";
// SPDX-License-Identifier: AGPL-3.0-or-later
// Copyright (C) 2024-2026 Gracker (Chris)
// This file is part of SmartPerfetto. See LICENSE for details.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.getPerfettoSqlDocsAssetPath = getPerfettoSqlDocsAssetPath;
exports.loadPerfettoSqlDocsAsset = loadPerfettoSqlDocsAsset;
exports.clearPerfettoSqlDocsCache = clearPerfettoSqlDocsCache;
exports.searchPerfettoSqlDocs = searchPerfettoSqlDocs;
exports.getPerfettoSqlModuleDoc = getPerfettoSqlModuleDoc;
exports.listPerfettoSqlModuleDocs = listPerfettoSqlModuleDocs;
exports.getPerfettoSqlModuleClosure = getPerfettoSqlModuleClosure;
exports.moduleCoveredByPerfettoSqlLineage = moduleCoveredByPerfettoSqlLineage;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
let cachedAsset;
let cachedModuleMap = null;
function getPerfettoSqlDocsAssetPath() {
    return path.resolve(__dirname, '../../data/perfettoSqlDocs.json');
}
function loadPerfettoSqlDocsAsset() {
    if (cachedAsset !== undefined)
        return cachedAsset;
    const assetPath = getPerfettoSqlDocsAssetPath();
    if (!fs.existsSync(assetPath)) {
        cachedAsset = null;
        return cachedAsset;
    }
    try {
        const parsed = JSON.parse(fs.readFileSync(assetPath, 'utf-8'));
        if (parsed.version !== 1
            || !Array.isArray(parsed.modules)
            || !Array.isArray(parsed.entries)
            || !parsed.symbolToModule
            || typeof parsed.symbolToModule !== 'object') {
            console.warn(`[PerfettoSqlDocs] Ignoring invalid docs asset: ${assetPath}`);
            cachedAsset = null;
            return cachedAsset;
        }
        cachedAsset = parsed;
        return cachedAsset;
    }
    catch (error) {
        console.warn(`[PerfettoSqlDocs] Failed to read docs asset ${assetPath}: ${error.message}`);
        cachedAsset = null;
        return cachedAsset;
    }
}
function clearPerfettoSqlDocsCache() {
    cachedAsset = undefined;
    cachedModuleMap = null;
}
function getModuleMap() {
    if (cachedModuleMap)
        return cachedModuleMap;
    cachedModuleMap = new Map();
    const asset = loadPerfettoSqlDocsAsset();
    for (const mod of asset?.modules ?? []) {
        cachedModuleMap.set(mod.module.toLowerCase(), mod);
    }
    return cachedModuleMap;
}
function tokensFor(query) {
    return query
        .toLowerCase()
        .split(/[\s_.:/-]+/)
        .map(t => t.trim())
        .filter(t => t.length >= 2);
}
function includesToken(value, token) {
    return typeof value === 'string' && value.toLowerCase().includes(token);
}
function scoreDocEntry(entry, query) {
    const lower = query.toLowerCase().trim();
    const tokens = tokensFor(query);
    const fields = [];
    let score = 0;
    const name = entry.name.toLowerCase();
    const moduleName = entry.module.toLowerCase();
    const desc = (entry.description || '').toLowerCase();
    if (name === lower) {
        score += 120;
        fields.push('name:exact');
    }
    else if (name.includes(lower)) {
        score += 70;
        fields.push('name:partial');
    }
    if (moduleName === lower) {
        score += 90;
        fields.push('module:exact');
    }
    else if (moduleName.includes(lower)) {
        score += 40;
        fields.push('module:partial');
    }
    if (desc.includes(lower)) {
        score += 20;
        fields.push('description:partial');
    }
    for (const token of tokens) {
        if (name.includes(token)) {
            score += 16;
            fields.push(`name:token:${token}`);
        }
        if (moduleName.includes(token)) {
            score += 12;
            fields.push(`module:token:${token}`);
        }
        if (desc.includes(token)) {
            score += 6;
            fields.push(`description:token:${token}`);
        }
        if (entry.tags?.some(tag => includesToken(tag, token))) {
            score += 5;
            fields.push(`tag:${token}`);
        }
        if (entry.columns?.some(col => includesToken(col.name, token) || includesToken(col.description, token) || includesToken(col.type, token))) {
            score += 10;
            fields.push(`column:${token}`);
        }
        if (entry.params?.some(param => includesToken(param.name, token) || includesToken(param.description, token) || includesToken(param.type, token))) {
            score += 8;
            fields.push(`param:${token}`);
        }
    }
    return { score, fields: [...new Set(fields)] };
}
function searchPerfettoSqlDocs(query, options = {}) {
    const asset = loadPerfettoSqlDocsAsset();
    if (!asset || !query.trim())
        return [];
    const results = [];
    const moduleFilter = options.module?.toLowerCase();
    for (const entry of asset.entries) {
        if (!options.includePrivate && (entry.visibility === 'private' || entry.name.startsWith('_'))) {
            continue;
        }
        if (options.type && entry.type !== options.type)
            continue;
        if (moduleFilter && entry.module.toLowerCase() !== moduleFilter)
            continue;
        const scored = scoreDocEntry(entry, query);
        if (scored.score > 0) {
            results.push({ entry, score: scored.score, matchedFields: scored.fields });
        }
    }
    results.sort((a, b) => b.score - a.score
        || a.entry.name.localeCompare(b.entry.name)
        || a.entry.module.localeCompare(b.entry.module));
    return results.slice(0, options.limit ?? 30);
}
function getPerfettoSqlModuleDoc(moduleName) {
    return getModuleMap().get(moduleName.toLowerCase());
}
function listPerfettoSqlModuleDocs(namespace) {
    const asset = loadPerfettoSqlDocsAsset();
    if (!asset)
        return [];
    const normalized = namespace?.trim().toLowerCase();
    return asset.modules
        .filter(mod => {
        if (!normalized)
            return true;
        const name = mod.module.toLowerCase();
        return name === normalized || name.startsWith(`${normalized}.`);
    })
        .sort((a, b) => a.module.localeCompare(b.module));
}
function getPerfettoSqlModuleClosure(moduleName) {
    const mod = getPerfettoSqlModuleDoc(moduleName);
    return mod?.transitiveIncludes ?? [];
}
function moduleCoveredByPerfettoSqlLineage(targetModule, declaredModule) {
    const target = targetModule.trim().toLowerCase();
    const declared = declaredModule.trim().toLowerCase();
    if (!target || !declared)
        return false;
    if (target === declared || target.startsWith(`${declared}.`))
        return true;
    for (const included of getPerfettoSqlModuleClosure(declared)) {
        const normalized = included.toLowerCase();
        if (target === normalized || target.startsWith(`${normalized}.`)) {
            return true;
        }
    }
    return false;
}
//# sourceMappingURL=perfettoSqlDocs.js.map