<?php
declare(strict_types=1);

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

function urbm_bridge_log(string $level, string $message, array $context = []): void
{
    $entry = array_merge([
        'time' => gmdate('c'),
        'level' => $level,
        'component' => 'webgui',
        'message' => $message,
    ], $context);
    @file_put_contents('/var/log/urbm.log', json_encode($entry, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND | LOCK_EX);
}

function urbm_json_error(int $status, string $message): void
{
    http_response_code($status);
    echo json_encode(['error' => $message], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
    exit;
}

$socket = '/run/urbm/urbm.sock';
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
$path = $_GET['path'] ?? '/v1/health';
$isSnapshotFileRequest = preg_match('#/snapshots/[^/]+/files(?:\?|$)#', $path) === 1;

if (!preg_match('#^/v1/[A-Za-z0-9_./?=&%:-]*$#', $path) || str_contains($path, '..')) {
    urbm_bridge_log('warn', 'invalid API path', ['path' => $path]);
    urbm_json_error(400, 'invalid API path');
}

if (!file_exists($socket)) {
    urbm_bridge_log('warn', 'daemon socket missing', ['path' => $path, 'socket' => $socket]);
    urbm_json_error(503, 'Der URBM-Daemon läuft nicht');
}

$curl = curl_init();
curl_setopt_array($curl, [
    CURLOPT_UNIX_SOCKET_PATH => $socket,
    CURLOPT_URL => 'http://localhost' . $path,
    CURLOPT_CUSTOMREQUEST => $method,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CONNECTTIMEOUT => 3,
    CURLOPT_TIMEOUT => $isSnapshotFileRequest ? 1250 : 310,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
]);

$body = file_get_contents('php://input');
if ($method !== 'GET' && $body !== false && $body !== '') {
    curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
}

$response = curl_exec($curl);
$status = (int)curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
$error = curl_error($curl);
curl_close($curl);

if ($response === false) {
    $message = 'Verbindung zum URBM-Daemon fehlgeschlagen: ' . $error;
    urbm_bridge_log('warn', 'daemon request failed', ['path' => $path, 'status' => 502, 'error' => $message]);
    urbm_json_error(502, $message);
}

if ($status <= 0) {
    $message = 'URBM-Daemon lieferte keine HTTP-Antwort';
    urbm_bridge_log('warn', 'daemon response missing', ['path' => $path, 'status' => 502, 'error' => $message]);
    urbm_json_error(502, $message);
}

if ($status >= 400) {
    $decoded = json_decode((string)$response, true);
    if (is_array($decoded) && isset($decoded['error']) && is_string($decoded['error'])) {
        $message = $decoded['error'];
    } else {
        $message = trim((string)$response);
    }
    if ($message === '') {
        $message = 'URBM-Daemon lieferte HTTP ' . $status . ' ohne Fehlertext';
    }
    urbm_bridge_log('warn', 'api request failed', ['path' => $path, 'status' => $status, 'error' => $message]);
    urbm_json_error($status, $message);
}

http_response_code($status);
echo $response;
