import { createReadStream, promises as fs } from 'fs';
import { dirname, basename } from 'path';
import type { AuditEvent, AuditQuery } from './types.js';

export async function queryAuditLogs(logPath: string, query: AuditQuery): Promise<AuditEvent[]> {
  const logs: AuditEvent[] = [];

  try {
    const content = await fs.readFile(logPath, 'utf-8');
    const lines = content.split('\n').filter(line => line.trim() !== '');

    for (const line of lines) {
      try {
        const event: AuditEvent = JSON.parse(line);
        if (matchesQuery(event, query)) {
          logs.push(event);
        }
      } catch {
        // Skip malformed lines
      }
    }
  } catch (err) {
    if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {
      throw err;
    }
  }

  return logs.sort((a, b) => a.timestamp - b.timestamp);
}

function matchesQuery(event: AuditEvent, query: AuditQuery): boolean {
  if (query.start_time && event.timestamp < query.start_time) {
    return false;
  }
  if (query.end_time && event.timestamp > query.end_time) {
    return false;
  }
  if (query.event_types && !query.event_types.includes(event.event_type)) {
    return false;
  }
  if (query.level && event.level !== query.level) {
    return false;
  }
  if (query.session_id) {
    const eventSessionId = (event.event as Record<string, unknown>).session_id as string | undefined;
    if (eventSessionId !== query.session_id) {
      return false;
    }
  }
  if (query.tool_name) {
    const eventToolName = (event.event as Record<string, unknown>).tool_name as string | undefined;
    if (eventToolName !== query.tool_name) {
      return false;
    }
  }

  return true;
}

export async function exportAuditLogs(logPath: string, query: AuditQuery, format: 'json' | 'csv'): Promise<string> {
  const logs = await queryAuditLogs(logPath, query);

  if (format === 'json') {
    return JSON.stringify(logs, null, 2);
  }

  // CSV format
  const headers = ['timestamp', 'level', 'event_type', 'event'];
  const rows = logs.map(log => {
    const eventStr = JSON.stringify(log.event).replace(/"/g, '""');
    return `${log.timestamp},${log.level},${log.event_type},"${eventStr}"`;
  });

  return [headers.join(','), ...rows].join('\n');
}
