#!/usr/bin/env php
<?php
declare(strict_types=1);

/**
 * Reconcile wg0 peers with pending/active remote-access sessions.
 *
 * Usage:
 *   php scripts/sync_wg_peers.php [--dry-run]
 *   php scripts/sync_wg_peers.php --apply
 */
require_once __DIR__ . '/../src/bootstrap.php';
require_once __DIR__ . '/../src/RemoteAccessRepository.php';

$dryRun = true;
foreach ($argv as $arg) {
    if ($arg === '--apply') {
        $dryRun = false;
    } elseif ($arg === '--dry-run' || $arg === '-n') {
        $dryRun = true;
    } elseif ($arg === '-h' || $arg === '--help') {
        fwrite(STDOUT, "Usage: php scripts/sync_wg_peers.php [--dry-run|--apply]\n");
        exit(0);
    }
}

RemoteAccessRepository::ensureSchema();

$livePeers = WireGuardPeerProvisioner::listPeerDumpRows();
$keep = RemoteAccessRepository::activeWireGuardSessionPublicKeys();
$reconciled = RemoteAccessRepository::reconcileActiveWireGuardPeers($dryRun);
$pruned = RemoteAccessRepository::pruneOrphanWireGuardPeers($dryRun);

fwrite(STDOUT, 'mode=' . ($dryRun ? 'dry-run' : 'apply') . "\n");
fwrite(STDOUT, 'provision_peers=' . (WireGuardPeerProvisioner::isEnabled() ? 'true' : 'false') . "\n");
fwrite(STDOUT, 'live_wg_peers=' . count($livePeers) . "\n");
fwrite(STDOUT, 'active_session_peers=' . count($keep) . "\n");
fwrite(STDOUT, 'reconciled_sessions=' . count($reconciled) . "\n");
fwrite(STDOUT, 'pruned_peers=' . count($pruned) . "\n");

foreach ($reconciled as $row) {
    $pub = (string) ($row['public_key'] ?? '');
    $short = strlen($pub) > 12 ? substr($pub, 0, 8) . '…' : $pub;
    fwrite(
        STDOUT,
        sprintf(
            "  reconcile %s allowed_ips=%s ok=%s\n",
            $short,
            (string) ($row['client_address'] ?? ''),
            ($row['ok'] ?? false) ? 'true' : 'false'
        )
    );
}

foreach ($livePeers as $row) {
    $pub = (string) ($row['public_key'] ?? '');
    $allowed = trim((string) ($row['allowed_ips'] ?? ''));
    $short = strlen($pub) > 12 ? substr($pub, 0, 8) . '…' : $pub;
    $broken = ($allowed === '' || $allowed === '(none)');
    $orphan = !in_array($pub, $keep, true);
    if (!$broken && !$orphan) {
        continue;
    }
    fwrite(
        STDOUT,
        sprintf(
            "  live %s allowed_ips=%s broken=%s orphan=%s\n",
            $short,
            $allowed === '' ? '(empty)' : $allowed,
            $broken ? 'true' : 'false',
            $orphan ? 'true' : 'false'
        )
    );
}

foreach ($pruned as $row) {
    $pub = $row['public_key'] ?? '';
    $short = strlen($pub) > 12 ? substr($pub, 0, 8) . '…' : $pub;
    fwrite(
        STDOUT,
        sprintf(
            "  pruned %s reason=%s allowed_ips=%s\n",
            $short,
            (string) ($row['reason'] ?? ''),
            (string) ($row['allowed_ips'] ?? '')
        )
    );
}
