/**
 * Fail2ban / auth.log helper block
 *
 * Diesen Block kannst du in andere Login-Skripte kopieren.
 * Idee:
 * - Bei fehlgeschlagenem Login genau EINE klare Logzeile schreiben
 * - Die Zeile landet per syslog/authpriv im auth.log
 * - Fail2ban matcht spaeter auf PREFIX_LOGIN_FAIL ... ip=<HOST> ...
 *
 * WICHTIG:
 * - Niemals Passwoerter loggen
 * - Benutzerinput immer auf eine Zeile zwingen
 * - Fuer andere Seiten einfach den App-Namen aendern, z. B.:
 *   authlog_login_fail('shop', $username, 'invalid-login');
 *   authlog_login_fail('admin', $username, 'empty-fields');
 */

/**
 * Ermittelt die Client-IP.
 *
 * Standard: REMOTE_ADDR.
 *
 * Falls du der Reverse-Proxy-Kette vertraust, wird zuerst die erste IP aus
 * X-Forwarded-For genommen. Wenn du das NICHT willst, die XFF-Logik entfernen.
 */
function authlog_client_ip(): string
{
    $xff = trim((string)($_SERVER['HTTP_X_FORWARDED_FOR'] ?? ''));
    if ($xff !== '') {
        $parts = array_map('trim', explode(',', $xff));
        if (isset($parts[0]) && filter_var($parts[0], FILTER_VALIDATE_IP)) {
            return $parts[0];
        }
    }

    $remoteAddr = trim((string)($_SERVER['REMOTE_ADDR'] ?? ''));
    if ($remoteAddr !== '' && filter_var($remoteAddr, FILTER_VALIDATE_IP)) {
        return $remoteAddr;
    }

    return '0.0.0.0';
}

/**
 * Macht aus "studio" -> "STUDIO".
 *
 * So kannst du pro Anwendung/Seite einen stabilen Prefix verwenden:
 * STUDIO_LOGIN_FAIL
 * SHOP_LOGIN_FAIL
 * ADMIN_LOGIN_FAIL
 */
function authlog_app_tag(string $appName): string
{
    $appName = preg_replace('/[^A-Za-z0-9_-]+/', '_', $appName) ?? 'APP';
    $appName = trim($appName, '_- ');
    if ($appName === '') {
        $appName = 'APP';
    }

    return strtoupper($appName);
}

/**
 * Schreibt einen fehlgeschlagenen Login sauber per syslog/authpriv.
 *
 * Beispiel-Logzeile:
 * STUDIO_LOGIN_FAIL user=max ip=192.168.1.10 reason=invalid-login uri=/studio/login.php
 *
 * Diese Struktur ist absichtlich simpel, damit Fail2ban spaeter leicht matchen kann.
 */
function authlog_login_fail(string $appName, string $username, string $reason): void
{
    $tag = authlog_app_tag($appName);
    $ip = authlog_client_ip();
    $uri = (string)($_SERVER['REQUEST_URI'] ?? '-');

    // Benutzerinput auf eine Zeile zwingen
    $username = preg_replace('/[\r\n]+/', ' ', trim($username)) ?? '-';
    $reason = preg_replace('/[\r\n]+/', ' ', trim($reason)) ?? 'unknown';
    $uri = preg_replace('/[\r\n]+/', ' ', trim($uri)) ?? '-';

    if ($username === '') {
        $username = '-';
    }
    if ($reason === '') {
        $reason = 'unknown';
    }
    if ($uri === '') {
        $uri = '-';
    }

    $message = sprintf(
        '%s_LOGIN_FAIL user=%s ip=%s reason=%s uri=%s',
        $tag,
        $username,
        $ip,
        $reason,
        $uri
    );

    // authpriv = sicherheitsrelevante Auth-Meldungen
    openlog($tag, LOG_PID, LOG_AUTHPRIV);
    syslog(LOG_WARNING, $message);
    closelog();
}
