import { makeSourceReader } from '../utils/source-reader.js';
import { stableHash } from '../utils/hash.js';
import { hasIgnoreAnnotation } from '../utils/ignore-annotation.js';
// console.log/.debug/.info in non-test source. warn/error are intentional. LOW.
export function detectConsoleLogsInProd(input) {
    const read = makeSourceReader(input.workspaceRoot, input.project);
    const findings = [];
    for (const rel of input.files) {
        if (!isAnalysable(rel))
            continue;
        const raw = read(rel);
        if (raw == null)
            continue;
        findings.push(...analyseFile(rel, raw));
    }
    return findings;
}
const LOG_RE = /\bconsole\.(log|debug|info)\s*\(/g;
function analyseFile(file, raw) {
    const out = [];
    for (const m of raw.matchAll(LOG_RE)) {
        const line = lineOf(raw, m.index);
        // Skip if the call is inside a line comment.
        const lineText = lineAt(raw, line);
        if (/^\s*\/\//.test(lineText))
            continue;
        if (hasIgnoreAnnotation(raw, line, 'console-log-prod'))
            continue;
        out.push({
            detectorId: 'console-log-prod',
            severity: 'low',
            confidence: 0.9,
            layer: 1,
            title: `console.${m[1]} in ${file}:${line}`,
            description: `\`console.${m[1]}\` leaks to stdout in production. Loggers configured for severity, redaction, or sampling do not see this output, and CI / serverless / browser consoles pollute with debug noise.`,
            evidence: [
                {
                    file,
                    range: { startLine: line, endLine: line },
                    snippet: snippetAround(raw, line),
                },
            ],
            suggestion: 'Route through the project logger (pino / winston / debug / your custom one). For temporary debugging, gate behind `if (process.env.DEBUG)` or remove before merging.',
            fingerprint: `console-log-prod:${stableHash(`${file}:${line}:${m[1]}`)}`,
        });
    }
    return out;
}
function lineAt(raw, line) {
    return raw.split('\n')[line - 1] ?? '';
}
function isAnalysable(file) {
    const posix = file.replace(/\\/g, '/');
    return (/\.(?:ts|tsx|mts|cts|js|jsx|mjs|cjs)$/.test(posix) &&
        !/\.d\.ts$/.test(posix) &&
        !/(^|\/)node_modules\//.test(posix) &&
        !/(?:^|\/)__tests__\//.test(posix) &&
        !/(?:^|\/)tests?\//.test(posix) &&
        !/(?:^|\/)scripts?\//.test(posix) &&
        !/\.test\.(?:ts|tsx|js|jsx)$/.test(posix) &&
        !/\.spec\.(?:ts|tsx|js|jsx)$/.test(posix));
}
function lineOf(raw, idx) {
    return raw.slice(0, idx).split('\n').length;
}
function snippetAround(raw, line) {
    const lines = raw.split('\n');
    const from = Math.max(0, line - 1);
    const to = Math.min(lines.length, line + 1);
    return lines.slice(from, to).join('\n');
}
//# sourceMappingURL=console-log-prod.js.map