<?php
declare(strict_types=1);

/**
 * Minimaler URL-Shortener:
 * - Liest Key→URL aus einer Textdatei (Whitespace-getrennt)
 * - Ignoriert leere Zeilen & Kommentare (# am Zeilenanfang)
 * - Leitet mit 302 (oder optional 301) weiter
 * - Case-sensitive Keys (a ≠ A)
 */

const MAPPING_FILE = __DIR__ . '/urls.txt';   // Pfad zur Mapping-Datei
const DEFAULT_STATUS = 302;                    // 302 = temporär, 301 = permanent
const ALLOW_SCHEMES = ['http', 'https'];      // Sicherheit: nur http/https

/**
 * Liest die Mapping-Datei in ein assoziatives Array: key => url
 */
function loadMap(string $file): array {
    if (!is_readable($file)) {
        return [];
    }
    $map = [];

    $lines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    foreach ($lines as $line) {
        // Kommentare überspringen
        if (preg_match('/^\s*#/', $line)) continue;

        // Format: <key><whitespace><url>
        // URL: alles bis zum Zeilenende, aber muss mit http/https beginnen
        if (preg_match('/^\s*(\S+)\s+(https?:\/\/\S+)\s*$/i', $line, $m)) {
            $key = $m[1];
            $url = $m[2];

            // Sicherheit: nur erlaubte Schemes
            $scheme = strtolower(parse_url($url, PHP_URL_SCHEME) ?? '');
            if (!in_array($scheme, ALLOW_SCHEMES, true)) {
                continue;
            }
            $map[$key] = $url;
        }
        // sonst: Zeile wird stillschweigend ignoriert
    }
    return $map;
}

/**
 * Ermittelt den Key aus:
 *   - ?k=KEY
 *   - oder Pfad /KEY (bei Rewrite auf index.php)
 */
function getKeyFromRequest(): ?string {
    // 1) Bevorzugt Query-Param ?k=...
    if (isset($_GET['k']) && $_GET['k'] !== '') {
        return trim((string)$_GET['k']);
    }
    // 2) Aus der Pfad-Komponente extrahieren (z.B. /A → "A")
    $path = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?? '/';
    $path = trim($path, '/');
    if ($path !== '' && $path !== 'index.php') {
        return $path;
    }
    return null;
}

/**
 * Optional: Erlaube ?status=301, um gezielt permanente Redirects zu senden.
 */
function getStatusCode(): int {
    $status = isset($_GET['status']) ? (int)$_GET['status'] : DEFAULT_STATUS;
    return ($status === 301) ? 301 : 302;
}

$map = loadMap(MAPPING_FILE);
$key = getKeyFromRequest();

if ($key !== null && isset($map[$key])) {
    $target = $map[$key];

    // Falls man zusätzliche Query-Parameter "mitnehmen" möchte, kann man
    // sie hier anhängen. Standardmäßig leiten wir 1:1 weiter.
    // Beispiel (auskommentiert):
    // $extra = $_GET;
    // unset($extra['k'], $extra['status']);
    // if (!empty($extra)) {
    //     $sep = (parse_url($target, PHP_URL_QUERY) === null) ? '?' : '&';
    //     $target .= $sep . http_build_query($extra);
    // }

    header('Location: ' . $target, true, getStatusCode());
    exit;
}

/* Nichts zurückgeben, keine Fehlermeldung */
http_response_code(204);                 // No Content
header('Content-Length: 0');
header('Cache-Control: no-store');       // optional
exit;
