#!/usr/bin/env bash
set -euo pipefail
#
# One-time: consolidate existing duplicate AI-log-review issues
# (degraded / partial_outage / cosmetic, source='log_review') by an evidence
# fingerprint, matching the going-forward evidence-key dedup added to
# process-log-review.php. The AI re-words a finding's title on every scan, so
# the old title-based signature spawned a new open issue for the same recurring
# error. This regroups the existing open rows by normalize(evidence), keeps one
# (with the summed count + the new evidence-based signature so future scans
# increment it), and marks the rest 'fixed'. Idempotent — singletons just get
# their signature rewritten; a second run finds nothing to merge.
#
echo "[dedup-log-review] consolidating duplicate log_review issues by evidence fingerprint"

/usr/bin/php <<'PHP'
<?php
try {
    $password = trim(shell_exec('cat /root/.my.cnf | grep password | cut -f2- -d='));
    $db = new PDO('mysql:host=127.0.0.1;dbname=whp;charset=utf8mb4', 'root', $password);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Same normalization as whp_review_evidence_key() in process-log-review.php.
    $evkey = function (string $evidence): string {
        $s = strtolower($evidence);
        $s = preg_replace('/^\s*\[[^\]]*\]\s*/', '', $s);
        $s = preg_replace('/^\s*\d{4}-\d{2}-\d{2}[ t]\d{2}:\d{2}:\d{2}\S*\s*/', '', $s);
        $s = preg_replace('/\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/', 'uuid', $s);
        $s = preg_replace('/0x[0-9a-f]+/', '0xhex', $s);
        $s = preg_replace('/\d+/', '#', $s);
        $s = preg_replace('/\s+/', ' ', $s);
        $s = trim($s);
        if (strlen($s) > 300) { $s = substr($s, 0, 300); }
        return $s;
    };

    $rows = $db->query(
        "SELECT id, site_id, category, occurrence_count, last_seen, evidence
         FROM whp.ai_monitor_issues
         WHERE status='open' AND source='log_review'
           AND evidence IS NOT NULL AND evidence <> ''
         ORDER BY id"
    )->fetchAll(PDO::FETCH_ASSOC);

    if (!$rows) { echo "[dedup-log-review] no open log_review issues with evidence; nothing to do\n"; exit(0); }

    // Group by (site_id, category, evidence fingerprint).
    $groups = [];
    foreach ($rows as $r) {
        $sid = ($r['site_id'] === null) ? '' : (string)$r['site_id'];
        $key = $sid . '|' . $r['category'] . '|' . $evkey((string)$r['evidence']);
        $groups[$key][] = $r;
    }

    $db->beginTransaction();
    $keep = $db->prepare(
        "UPDATE whp.ai_monitor_issues
         SET occurrence_count=?, last_seen=?, signature=? WHERE id=?");
    $resolve = $db->prepare(
        "UPDATE whp.ai_monitor_issues
         SET status='fixed', auto_resolved_at=COALESCE(auto_resolved_at,NOW()),
             status_changed_by='dedup-merge', status_changed_at=NOW()
         WHERE id=? AND status='open'");

    $mergedGroups = 0; $resolvedRows = 0; $sigRewrites = 0;
    foreach ($groups as $key => $g) {
        [$sid, $cat, $ek] = explode('|', $key, 3);
        $sig    = hash('sha256', "review:{$sid}:{$cat}:{$ek}");
        $keeper = $g[0]; // MIN(id) — rows fetched ORDER BY id
        $sum    = 0; $maxLast = $keeper['last_seen'];
        foreach ($g as $r) {
            $sum += (int)$r['occurrence_count'];
            if ($r['last_seen'] > $maxLast) { $maxLast = $r['last_seen']; }
        }
        $keep->execute([$sum, $maxLast, $sig, $keeper['id']]);
        $sigRewrites++;
        if (count($g) > 1) {
            $mergedGroups++;
            for ($i = 1; $i < count($g); $i++) {
                $resolve->execute([$g[$i]['id']]);
                $resolvedRows += $resolve->rowCount();
            }
        }
    }
    $db->commit();
    echo "[dedup-log-review] scanned " . count($rows) . " open rows, "
       . count($groups) . " distinct problems; merged $mergedGroups duplicate group(s), "
       . "resolved $resolvedRows duplicate row(s), rewrote $sigRewrites signature(s) to evidence keys\n";
} catch (Throwable $e) {
    // Never abort the update for a best-effort data cleanup.
    if (isset($db) && $db->inTransaction()) { $db->rollBack(); }
    echo "[dedup-log-review] skipped (non-fatal): " . $e->getMessage() . "\n";
    exit(0);
}
PHP

echo "[dedup-log-review] done"
