<?php
// api/coraza-rules-recent-matches.php — last 20 audit.log events for one rule.
require_once('/docker/whp/web/libs/permission_checker.php');
header('Content-Type: application/json');
if (!is_root_user()) { http_response_code(403); echo '[]'; return; }
$rid = (int)($_GET['rule_id'] ?? 0);
if ($rid < 1) { echo '[]'; return; }

$path = '/var/log/coraza/audit.log';
if (!file_exists($path)) { echo '[]'; return; }
$out = [];
$fp = fopen($path, 'r');
if (!$fp) { echo '[]'; return; }
$buf = '';
$pos = filesize($path);
$chunk = 262144;
while ($pos > 0 && count($out) < 20) {
    $read = min($chunk, $pos);
    $pos -= $read;
    fseek($fp, $pos);
    $buf = fread($fp, $read) . $buf;
    $lines = explode("\n", $buf);
    $buf = array_shift($lines);  // hold partial first line for next iter
    foreach (array_reverse($lines) as $line) {
        if ($line === '') continue;
        $j = json_decode($line, true);
        if (!$j || !isset($j['messages'])) continue;
        $matched = false;
        foreach ($j['messages'] as $msg) {
            if ((int)($msg['data']['id'] ?? 0) === $rid) { $matched = true; break; }
        }
        if (!$matched) continue;
        $out[] = [
            'ts'     => $j['transaction']['timestamp'] ?? '',
            'client' => $j['transaction']['client_ip'] ?? '',
            'host'   => $j['transaction']['server_id'] ?? '',
            'method' => $j['transaction']['request']['method'] ?? '',
            'uri'    => $j['transaction']['request']['uri'] ?? '',
        ];
        if (count($out) >= 20) break;
    }
}
fclose($fp);
echo json_encode($out);
