<?php
require_once __DIR__ . '/common.php';

function mpb_status_token_ok(): bool {
    $token = '';
    if (!empty($_SERVER['HTTP_X_MP_BALANCER_TOKEN'])) {
        $token = trim((string)$_SERVER['HTTP_X_MP_BALANCER_TOKEN']);
    }
    if ($token === '' && isset($_GET['token'])) {
        $token = trim((string)$_GET['token']);
    }
    return defined('MP_BALANCER_TOKEN') && hash_equals((string)MP_BALANCER_TOKEN, $token);
}

function mpb_read_proc_stat(): array {
    $line = @file('/proc/stat')[0] ?? '';
    $parts = preg_split('/\s+/', trim($line));
    array_shift($parts);
    $vals = array_map('intval', $parts ?: []);
    $idle = ($vals[3] ?? 0) + ($vals[4] ?? 0);
    $total = array_sum($vals);
    return ['idle'=>$idle, 'total'=>$total];
}

function mpb_cpu_percent(): float {
    $a = mpb_read_proc_stat();
    usleep(220000);
    $b = mpb_read_proc_stat();
    $total = max(1, $b['total'] - $a['total']);
    $idle  = max(0, $b['idle'] - $a['idle']);
    $used = 100.0 * (1.0 - ($idle / $total));
    return round(max(0, min(100, $used)), 2);
}

function mpb_meminfo(): array {
    $raw = @file('/proc/meminfo') ?: [];
    $m = [];
    foreach ($raw as $line) {
        if (preg_match('/^([A-Za-z_()]+):\s+(\d+)/', $line, $mm)) {
            $m[$mm[1]] = (int)$mm[2] * 1024;
        }
    }
    $total = (int)($m['MemTotal'] ?? 0);
    $avail = (int)($m['MemAvailable'] ?? ($m['MemFree'] ?? 0));
    $used = max(0, $total - $avail);
    $swapTotal = (int)($m['SwapTotal'] ?? 0);
    $swapFree = (int)($m['SwapFree'] ?? 0);
    $swapUsed = max(0, $swapTotal - $swapFree);
    return [
        'total'=>$total,
        'used'=>$used,
        'free'=>$avail,
        'percent'=>$total > 0 ? round(($used / $total) * 100, 2) : 0,
        'swap_total'=>$swapTotal,
        'swap_used'=>$swapUsed,
        'swap_percent'=>$swapTotal > 0 ? round(($swapUsed / $swapTotal) * 100, 2) : 0,
    ];
}

function mpb_diskinfo(string $path = '/'): array {
    $total = (int)@disk_total_space($path);
    $free  = (int)@disk_free_space($path);
    $used  = max(0, $total - $free);
    return [
        'path'=>$path,
        'total'=>$total,
        'used'=>$used,
        'free'=>$free,
        'percent'=>$total > 0 ? round(($used / $total) * 100, 2) : 0,
    ];
}

function mpb_net_totals(): array {
    $rx = 0; $tx = 0; $ifaces = [];
    $lines = @file('/proc/net/dev') ?: [];
    foreach ($lines as $line) {
        if (strpos($line, ':') === false) continue;
        [$iface, $data] = array_map('trim', explode(':', $line, 2));
        if ($iface === 'lo') continue;
        $p = preg_split('/\s+/', trim($data));
        if (count($p) < 16) continue;
        $irx = (int)$p[0];
        $itx = (int)$p[8];
        $rx += $irx; $tx += $itx;
        $ifaces[$iface] = ['rx'=>$irx, 'tx'=>$itx];
    }
    return ['rx'=>$rx, 'tx'=>$tx, 'interfaces'=>$ifaces, 'time'=>microtime(true)];
}

function mpb_net_speed(): array {
    $file = '/tmp/mpb_net_prev.json';
    $now = mpb_net_totals();
    $rxBps = 0; $txBps = 0;
    $prev = [];
    if (is_file($file)) {
        $prev = json_decode((string)@file_get_contents($file), true) ?: [];
    }
    if (!empty($prev['time'])) {
        $dt = max(0.1, (float)$now['time'] - (float)$prev['time']);
        $rxBps = max(0, (int)(($now['rx'] - (int)($prev['rx'] ?? 0)) / $dt));
        $txBps = max(0, (int)(($now['tx'] - (int)($prev['tx'] ?? 0)) / $dt));
    }
    @file_put_contents($file, json_encode($now));
    return [
        'rx_total'=>$now['rx'],
        'tx_total'=>$now['tx'],
        'rx_bps'=>$rxBps,
        'tx_bps'=>$txBps,
        'interfaces'=>$now['interfaces'],
    ];
}

function mpb_cmd(string $cmd): string {
    return trim((string)@shell_exec($cmd . ' 2>/dev/null'));
}

function mpb_service_active(string $name): bool {
    $r = mpb_cmd('systemctl is-active ' . escapeshellarg($name));
    return $r === 'active';
}

function mpb_uptime_seconds(): int {
    $raw = trim((string)@file_get_contents('/proc/uptime'));
    $p = preg_split('/\s+/', $raw);
    return (int)floor((float)($p[0] ?? 0));
}

function mpb_connections(): array {
    $est80  = (int)mpb_cmd("ss -Htan state established '( sport = :80 )' | wc -l");
    $est443 = (int)mpb_cmd("ss -Htan state established '( sport = :443 )' | wc -l");
    $all80  = (int)mpb_cmd("ss -Htan '( sport = :80 )' | wc -l");
    $all443 = (int)mpb_cmd("ss -Htan '( sport = :443 )' | wc -l");
    return [
        'http_established'=>$est80,
        'https_established'=>$est443,
        'established'=>$est80 + $est443,
        'total'=>$all80 + $all443,
    ];
}

function mpb_format_version(): string {
    return defined('MP_BALANCER_VERSION') ? (string)MP_BALANCER_VERSION : '2.0';
}

function mpb_sessions_dir(): string {
    return '/tmp/mpb_sessions';
}

function mpb_active_stream_sessions(int $maxAge = 900): array {
    $dir = mpb_sessions_dir();
    $items = [];
    if (!is_dir($dir)) return ['count'=>0, 'by_type'=>[], 'items'=>[]];
    foreach (glob($dir . '/*.json') ?: [] as $file) {
        $j = json_decode((string)@file_get_contents($file), true);
        if (!is_array($j)) { @unlink($file); continue; }
        $seen = (int)($j['last_seen'] ?? 0);
        if ($seen <= 0 || time() - $seen > $maxAge) {
            if (time() - $seen > 1800) @unlink($file);
            continue;
        }
        $j['age_seconds'] = time() - $seen;
        $j['duration_seconds'] = time() - (int)($j['started_at'] ?? time());
        $j['user_agent_short'] = substr((string)($j['user_agent'] ?? ''), 0, 180);
        $items[] = $j;
    }
    usort($items, function($a, $b) { return (int)($b['last_seen'] ?? 0) <=> (int)($a['last_seen'] ?? 0); });
    $by = [];
    foreach ($items as $i) {
        $t = (string)($i['type'] ?? 'outro');
        if ($t === '') $t = 'outro';
        $by[$t] = ($by[$t] ?? 0) + 1;
    }
    return ['count'=>count($items), 'by_type'=>$by, 'items'=>$items];
}

$panel = mpb_api('status', [], 15);

if (isset($_GET['metrics']) && $_GET['metrics'] === '1') {
    if (!mpb_status_token_ok()) {
        http_response_code(403);
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode(['ok'=>false,'error'=>'token_invalido'], JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
        exit;
    }

    $load = sys_getloadavg();
    $phpFpmActive = false;
    foreach (glob('/run/php/php*-fpm.sock') ?: [] as $sock) {
        if (is_file($sock) || is_link($sock)) { $phpFpmActive = true; break; }
    }

    $metrics = [
        'ok'=>true,
        'balancer'=>'online',
        'version'=>mpb_format_version(),
        'url'=>mpb_base(),
        'hostname'=>php_uname('n'),
        'time'=>date('Y-m-d H:i:s'),
        'timestamp'=>time(),
        'uptime_seconds'=>mpb_uptime_seconds(),
        'cpu'=>[
            'percent'=>mpb_cpu_percent(),
            'load1'=>round((float)($load[0] ?? 0), 2),
            'load5'=>round((float)($load[1] ?? 0), 2),
            'load15'=>round((float)($load[2] ?? 0), 2),
            'cores'=>(int)trim((string)mpb_cmd('nproc')),
        ],
        'memory'=>mpb_meminfo(),
        'disk'=>mpb_diskinfo('/'),
        'network'=>mpb_net_speed(),
        'services'=>[
            'nginx'=>mpb_service_active('nginx'),
            'php_fpm'=>$phpFpmActive,
            'ffmpeg'=>(mpb_cmd('command -v ffmpeg') !== ''),
        ],
        'processes'=>[
            'ffmpeg'=>(int)mpb_cmd('pgrep -cf ffmpeg'),
            'nginx'=>(int)mpb_cmd('pgrep -cf nginx'),
            'php_fpm'=>(int)mpb_cmd("pgrep -cf 'php.*fpm'"),
        ],
        'connections'=>mpb_connections(),
        'active_streams'=>mpb_active_stream_sessions(),
        'panel'=>$panel,
    ];

    header('Content-Type: application/json; charset=utf-8');
    echo json_encode($metrics, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT);
    exit;
}

header('Content-Type: application/json; charset=utf-8');
echo json_encode(['ok'=>true,'balancer'=>'online','version'=>mpb_format_version(),'panel'=>$panel,'url'=>mpb_base(),'time'=>date('Y-m-d H:i:s')], JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT);
