<?php

declare(strict_types=1);

require_once __DIR__ . '/bootstrap.php';

function app_client_ip(): string
{
    return (string)($_SERVER['REMOTE_ADDR'] ?? 'unknown');
}

/**
 * Records an attempt in the given bucket and reports whether the caller is
 * still within the allowed rate. Call before doing the sensitive work (auth
 * check, mail dispatch, account creation); if this returns false, show a
 * generic "too many attempts" message without processing the request, so a
 * bucket also can't be used to enumerate valid accounts by timing.
 */
function app_rate_limit_check(PDO $pdo, string $bucket, int $maxAttempts, int $windowSeconds): bool
{
    $pdo->prepare('INSERT INTO rate_limit_attempts (bucket) VALUES (?)')->execute([$bucket]);

    // Opportunistic cleanup so the table doesn't grow unbounded; scoped to
    // this bucket to keep each call cheap.
    $pdo->prepare('DELETE FROM rate_limit_attempts WHERE bucket = ? AND created_at < DATE_SUB(NOW(), INTERVAL ? SECOND)')
        ->execute([$bucket, $windowSeconds]);

    $stmt = $pdo->prepare(
        'SELECT COUNT(*) FROM rate_limit_attempts WHERE bucket = ? AND created_at >= DATE_SUB(NOW(), INTERVAL ? SECOND)'
    );
    $stmt->execute([$bucket, $windowSeconds]);

    return (int)$stmt->fetchColumn() <= $maxAttempts;
}
