<?php
/**
 * touch.php — Reusable "open a gate from the Touch App" endpoint.
 *
 *   GET /touch.php?token=<token>&user=<name>[&gate=<key>]
 *
 * Validates the touch token, logs the event, and fires the relay for the
 * requested gate. The gate <key> maps to a relay URL in config.php's GATES
 * array; if omitted, DEFAULT_GATE is used. Each server's config.php defines
 * its own gates, so the same code opens the correct barrier everywhere, and
 * adding a future gate is just one line in GATES — no code change.
 *
 * kolmentouch.php is a thin back-compat shim that includes this file.
 */

require_once __DIR__ . '/config.php';

$token   = $_GET['token'] ?? '';
$user    = preg_replace('/[^a-zA-Z0-9_\-]/', '', $_GET['user'] ?? '');
$gateKey = preg_replace('/[^a-zA-Z0-9_\-]/', '', $_GET['gate'] ?? '');
$now     = date('YmdHis');
$fullUrl = 'http://' . ($_SERVER['HTTP_HOST'] ?? 'unknown') . ($_SERVER['REQUEST_URI'] ?? '');
$log     = $now . ';user=' . $user . ';gate=' . ($gateKey !== '' ? $gateKey : '(default)');

$conn = dbConnect();

// ── No token ────────────────────────────────────────────────────────────────
if ($token === '') {
    http_response_code(401);
    touchLog($conn, $now, $user, 'Touch', 'denied', $fullUrl);
    mysqli_close($conn);
    writeLog('kolmentouch.txt', $log . ';no_token');
    die();
}

// ── Look up token ───────────────────────────────────────────────────────────
$stmt = mysqli_prepare($conn, 'SELECT tokenid, label FROM tokens WHERE token = ? AND active = 1 LIMIT 1');
mysqli_stmt_bind_param($stmt, 's', $token);
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
$valid   = mysqli_stmt_num_rows($stmt) > 0;
$tokenId = null; $label = 'Touch';
if ($valid) {
    mysqli_stmt_bind_result($stmt, $tokenId, $label);
    mysqli_stmt_fetch($stmt);
}
mysqli_stmt_close($stmt);

$device = 'Touch:' . $label;

// ── Invalid token ───────────────────────────────────────────────────────────
if (!$valid) {
    http_response_code(403);
    touchLog($conn, $now, $user, $device, 'denied', $fullUrl);
    mysqli_close($conn);
    writeLog('kolmentouch.txt', $log . ';invalid_token');
    die();
}

// ── Resolve which barrier to open ───────────────────────────────────────────
$relayUrl = resolveGate($conn, $gateKey);
if ($relayUrl === '') {
    http_response_code(500);
    touchLog($conn, $now, $user, $device, 'denied', $fullUrl);
    mysqli_close($conn);
    writeLog('kolmentouch.txt', $log . ';unknown_gate');
    die();
}

// ── Valid: mark used, log allowed, open the gate ────────────────────────────
$upd = mysqli_prepare($conn, 'UPDATE tokens SET last_used = NOW() WHERE tokenid = ?');
mysqli_stmt_bind_param($upd, 'i', $tokenId);
mysqli_stmt_execute($upd);
mysqli_stmt_close($upd);

touchLog($conn, $now, $user, $device, 'allowed', null);
mysqli_close($conn);

$relay = triggerRelay($relayUrl);
writeLog('kolmentouch.txt', $log . ';' . $relay);

/** Insert a touch event into the access log. */
function touchLog(mysqli $conn, string $now, string $user, string $device, string $status, ?string $url): void {
    if ($url === null) {
        $ins = mysqli_prepare($conn, 'INSERT INTO logs (time, lp, device, status, url) VALUES (?, ?, ?, ?, NULL)');
        mysqli_stmt_bind_param($ins, 'ssss', $now, $user, $device, $status);
    } else {
        $ins = mysqli_prepare($conn, 'INSERT INTO logs (time, lp, device, status, url) VALUES (?, ?, ?, ?, ?)');
        mysqli_stmt_bind_param($ins, 'sssss', $now, $user, $device, $status, $url);
    }
    mysqli_stmt_execute($ins);
    mysqli_stmt_close($ins);
}

/**
 * Map a gate key to its relay URL. Prefers the `gates` table (managed in
 * Settings); an empty key resolves to the default gate. Falls back to
 * config.php's GATES / GATE_RELAY_URL if the table is missing or has no match.
 * Returns '' when no gate can be resolved.
 */
function resolveGate(mysqli $conn, string $key): string {
    try {
        if ($key !== '') {
            $stmt = mysqli_prepare($conn, 'SELECT relay_url FROM gates WHERE gatekey = ? LIMIT 1');
            mysqli_stmt_bind_param($stmt, 's', $key);
        } else {
            $stmt = mysqli_prepare($conn, 'SELECT relay_url FROM gates WHERE is_default = 1 ORDER BY gateid LIMIT 1');
        }
        mysqli_stmt_execute($stmt);
        $row = mysqli_fetch_row(mysqli_stmt_get_result($stmt));
        mysqli_stmt_close($stmt);
        if ($row) return $row[0];
    } catch (\Throwable $e) {
        // gates table absent — fall through to config
    }
    if ($key !== '' && defined('GATES') && isset(GATES[$key])) return GATES[$key];
    if ($key === '') {
        if (defined('GATES') && defined('DEFAULT_GATE') && isset(GATES[DEFAULT_GATE])) return GATES[DEFAULT_GATE];
        if (defined('GATE_RELAY_URL')) return GATE_RELAY_URL;
    }
    return '';
}
