// engine/audit-trail/query.ts — Query the audit JSONL log with filters (SPEC-167)
import { isNodeError, readJsonlLines } from './utils.js';
const DEFAULT_LIMIT = 100;
const MAX_LIMIT = 1000;
/** Parse all valid AuditEvent lines from an array of raw JSONL strings. */
function parseLines(lines) {
    return lines.flatMap((line) => {
        try {
            return [JSON.parse(line)];
        }
        catch {
            return [];
        }
    });
}
/** Apply query filters to an event. Returns true if the event matches all criteria. */
function matchesFilter(event, query) {
    if (query.specId !== undefined && event.specId !== query.specId) {
        return false;
    }
    if (query.userId !== undefined && event.userId !== query.userId) {
        return false;
    }
    if (query.eventType !== undefined && event.eventType !== query.eventType) {
        return false;
    }
    if (query.from !== undefined && event.timestamp < query.from) {
        return false;
    }
    if (query.to !== undefined && event.timestamp > query.to) {
        return false;
    }
    return true;
}
/**
 * Query the audit log JSONL file at filePath using the provided filters.
 * Returns matching events up to the configured limit, in ascending timestamp order.
 */
export async function queryAuditLog(filePath, query) {
    let lines;
    try {
        lines = await readJsonlLines(filePath);
    }
    catch (err) {
        if (isNodeError(err) && err.code === 'ENOENT') {
            return { events: [], total: 0, truncated: false };
        }
        throw err;
    }
    const all = parseLines(lines);
    const filtered = all.filter((ev) => matchesFilter(ev, query));
    const limit = Math.min(query.limit ?? DEFAULT_LIMIT, MAX_LIMIT);
    const truncated = filtered.length > limit;
    const events = truncated ? filtered.slice(0, limit) : filtered;
    return {
        events,
        total: filtered.length,
        truncated,
    };
}
//# sourceMappingURL=query.js.map