<?php
/**
 * Active sessions API.
 *
 * GET  ?action=list               -> JSON list of active nonce rows. Scoped to
 *                                    AUTH_USER unless the caller is root.
 * POST ?action=terminate          -> body: nonce=<sha1>. Deletes the row if the
 *                                    caller owns it (or is root).
 * POST ?action=terminate_user     -> body: user=<username>. Root-only bulk.
 *
 * auto-prepend.php handles auth, nonce validation, and CSRF (the latter on
 * POSTs); we just verify AUTH_USER is set and authorize per-row.
 */

header('Content-Type: application/json');

if (!defined('AUTH_USER')) {
    http_response_code(403);
    echo json_encode(['success' => false, 'error' => 'Not authenticated']);
    exit;
}

$action = $_REQUEST['action'] ?? 'list';
$is_root = (AUTH_USER === 'root');
$current_session_nonce = $_SESSION['nonce'] ?? null;

// $SecMan is normally instantiated by auto-prepend; fall back to a fresh
// instance if the page-context isn't carrying it (e.g., direct cron-style
// invocations during smoke tests).
if (!isset($SecMan) || !($SecMan instanceof security_wrapper)) {
    require_once('/docker/whp/web/libs/security.php');
    $SecMan = new security_wrapper();
}

switch ($action) {
    case 'list':
        $rows = $SecMan->list_nonces($is_root ? null : AUTH_USER);
        $out = [];
        foreach ($rows as $r) {
            $out[] = [
                'nonce'        => $r['nonce'],
                'user'         => $r['user'],
                'ip'           => $r['ip'],
                'last_time'    => (int)$r['last_time'],
                'persist'      => !empty($r['persist']),
                'is_current'   => $current_session_nonce !== null && $r['nonce'] === $current_session_nonce,
            ];
        }
        echo json_encode(['success' => true, 'sessions' => $out]);
        break;

    case 'terminate':
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            http_response_code(405);
            echo json_encode(['success' => false, 'error' => 'Method not allowed']);
            exit;
        }
        $nonce = $_POST['nonce'] ?? '';
        if ($nonce === '' || !preg_match('/^[a-f0-9]{40}$/', $nonce)) {
            http_response_code(400);
            echo json_encode(['success' => false, 'error' => 'Invalid nonce']);
            exit;
        }
        $row = $SecMan->get_nonce($nonce);
        if (!$row) {
            // Already gone — treat as success (idempotent).
            echo json_encode(['success' => true, 'already_gone' => true]);
            exit;
        }
        // Authorize: root can kill any row; user can only kill their own.
        if (!$is_root && $row['user'] !== AUTH_USER) {
            http_response_code(403);
            echo json_encode(['success' => false, 'error' => 'Not authorized to terminate this session']);
            exit;
        }
        $SecMan->delete_nonce($nonce);
        echo json_encode([
            'success'     => true,
            'self_terminated' => $current_session_nonce !== null && $nonce === $current_session_nonce,
        ]);
        break;

    case 'terminate_user':
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            http_response_code(405);
            echo json_encode(['success' => false, 'error' => 'Method not allowed']);
            exit;
        }
        if (!$is_root) {
            http_response_code(403);
            echo json_encode(['success' => false, 'error' => 'Root only']);
            exit;
        }
        $target_user = $_POST['user'] ?? '';
        if ($target_user === '' || !preg_match('/^[a-zA-Z0-9_-]+$/', $target_user)) {
            http_response_code(400);
            echo json_encode(['success' => false, 'error' => 'Invalid username']);
            exit;
        }
        $SecMan->delete_nonces_by_user($target_user);
        echo json_encode(['success' => true]);
        break;

    default:
        http_response_code(400);
        echo json_encode(['success' => false, 'error' => 'Unknown action: ' . $action]);
        break;
}
