"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.estimateTokenCount = estimateTokenCount;
exports.stableChunkId = stableChunkId;
exports.languageForPath = languageForPath;
exports.detectSourceSymbol = detectSourceSymbol;
exports.chunkSourceBySymbols = chunkSourceBySymbols;
exports.chunkTextByParagraphs = chunkTextByParagraphs;
const crypto_1 = require("crypto");
const path = __importStar(require("path"));
function estimateTokenCount(text) {
    return Math.max(1, Math.round(text.length / 4));
}
function stableChunkId(parts, length = 16) {
    return (0, crypto_1.createHash)('sha256')
        .update(parts.map(part => String(part)).join('|'))
        .digest('hex')
        .slice(0, length);
}
function languageForPath(relativePath) {
    const ext = path.extname(relativePath);
    if (ext === '.kt' || ext === '.kts')
        return 'kotlin';
    if (ext === '.java')
        return 'java';
    if (ext === '.c')
        return 'c';
    if (ext === '.cc' || ext === '.cpp' || ext === '.cxx' || ext === '.h' || ext === '.hpp')
        return 'cpp';
    if (ext === '.rs')
        return 'rust';
    if (ext === '.go')
        return 'go';
    if (ext === '.py')
        return 'py';
    return 'unknown';
}
function detectSourceSymbol(line) {
    const classMatch = line.match(/\b(?:class|object|interface|enum\s+class|struct)\s+([A-Za-z_][A-Za-z0-9_]*)/);
    if (classMatch?.[1])
        return classMatch[1];
    const kotlinFun = line.match(/\bfun\s+([A-Za-z_][A-Za-z0-9_]*)\s*\(/);
    if (kotlinFun?.[1])
        return kotlinFun[1];
    const cLikeFunction = line.match(/\b(?:[A-Za-z_][A-Za-z0-9_:<>~*&\s]+)\s+([A-Za-z_~][A-Za-z0-9_:~]*)\s*\([^;]*\)\s*(?:const\s*)?(?:noexcept\s*)?(?:override\s*)?\{/);
    if (cLikeFunction?.[1])
        return cLikeFunction[1].split('::').pop();
    const javaMethod = line.match(/\b(?:public|private|protected|internal|static|final|suspend|override|\s)+[A-Za-z0-9_<>,.?[\]\s]+\s+([A-Za-z_][A-Za-z0-9_]*)\s*\([^;]*\)\s*\{/);
    return javaMethod?.[1];
}
function chunkSourceBySymbols(content, maxChars) {
    const normalized = content.replace(/\r\n?/g, '\n');
    if (normalized.trim().length === 0)
        return [];
    const lines = normalized.split('\n');
    const boundaries = new Set([0]);
    for (let i = 0; i < lines.length; i++) {
        if (detectSourceSymbol(lines[i]))
            boundaries.add(i);
    }
    boundaries.add(lines.length);
    const sorted = Array.from(boundaries).sort((a, b) => a - b);
    const sections = [];
    for (let i = 0; i < sorted.length - 1; i++) {
        const start = sorted[i];
        const end = sorted[i + 1];
        if (end <= start)
            continue;
        const text = lines.slice(start, end).join('\n').trim();
        if (!text)
            continue;
        sections.push({
            text,
            startLine: start + 1,
            endLine: end,
            symbol: detectSourceSymbol(lines[start]),
        });
    }
    const out = [];
    for (const section of sections) {
        if (section.text.length <= maxChars * 2) {
            out.push(section);
            continue;
        }
        const sectionLines = section.text.split('\n');
        let startLine = section.startLine;
        let buf = [];
        let bufChars = 0;
        for (const line of sectionLines) {
            if (bufChars === 0 && line.length > maxChars) {
                let cursor = 0;
                while (cursor < line.length) {
                    const piece = line.slice(cursor, cursor + maxChars);
                    out.push({
                        text: piece,
                        startLine,
                        endLine: startLine,
                        symbol: section.symbol,
                    });
                    cursor += maxChars;
                }
                startLine += 1;
                continue;
            }
            if (bufChars > 0 && bufChars + line.length + 1 > maxChars) {
                out.push({
                    text: buf.join('\n'),
                    startLine,
                    endLine: startLine + buf.length - 1,
                    symbol: section.symbol,
                });
                startLine += buf.length;
                buf = [];
                bufChars = 0;
            }
            buf.push(line);
            bufChars += line.length + 1;
        }
        if (buf.length > 0) {
            out.push({
                text: buf.join('\n'),
                startLine,
                endLine: startLine + buf.length - 1,
                symbol: section.symbol,
            });
        }
    }
    return out;
}
function chunkTextByParagraphs(text, maxChars) {
    const trimmed = text.trim();
    if (trimmed.length === 0)
        return [];
    const paragraphs = trimmed
        .split(/\n\s*\n+/)
        .map(p => p.trim())
        .filter(p => p.length > 0);
    const out = [];
    let cursor = 0;
    let buf = '';
    let bufStart = 0;
    for (const p of paragraphs) {
        if (buf.length === 0) {
            buf = p;
            bufStart = cursor;
        }
        else if (buf.length + 2 + p.length <= maxChars) {
            buf += '\n\n' + p;
        }
        else {
            out.push({ text: buf, offset: bufStart });
            buf = p;
            bufStart = cursor;
        }
        cursor += p.length + 2;
    }
    if (buf.length > 0)
        out.push({ text: buf, offset: bufStart });
    return out;
}
//# sourceMappingURL=baseIngester.js.map