<?php

namespace WtbFirewall\RateLimit;

// Prevent direct access.
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Denne klassen brukes til å håndtere loggen for rate limit og 404 monitor delen.
 * Dvs tabellen wtb_firewall_rate_counters
 */
class RateLimitLog {

    /**
     * Logfører en request i databasen.
     * 
     */
    public function logRequest() {

        $ip = inet_pton(\WtbFirewall\Helpers\IpHelper::getVisitorIP());

        if ($ip !== false) {
            $this->logEntry($ip, 1);
        }
    }

    /**
     * Logfører en 404 feil i databasen.
     * 
     */
    public function log404() {

        $ip = inet_pton(\WtbFirewall\Helpers\IpHelper::getVisitorIP());

        if ($ip !== false) {
            $this->logEntry($ip, 2);
        }
    }

    /**
     * 
     * @return int Antall requests siste 60 sekunder fra nåværende IP.
     */
    public function getRequestCount(): int {

        $ip = inet_pton(\WtbFirewall\Helpers\IpHelper::getVisitorIP());

        if ($ip !== false) {
            return $this->getCount($ip, 1);
        }
    }

    /**
     * 
     * @return int Antall 404 feil siste 60 sekunder fra nåværende IP.
     */
    public function get404Count(): int {

        $ip = inet_pton(\WtbFirewall\Helpers\IpHelper::getVisitorIP());

        if ($ip !== false) {
            return $this->getCount($ip, 2);
        }
    }

    /**
     * Oppretter ny eller oppdaterer eksisterende request/404 info for IP.
     *      
     * @param string $ip     
     * @param int $counterType
     * @return void
     */
    private function logEntry(string $ip, int $counterType): void {
        global $wpdb;

        $table = $wpdb->prefix . 'wtb_firewall_rate_counters';

        $timeWindow = intdiv(time(), 30);

        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- prepared below
        $sql = "
        INSERT INTO {$table} (ip, time_window, counter, counter_type)
        VALUES (%s, %d, 1, %d)
        ON DUPLICATE KEY UPDATE counter = counter + 1
    ";

        $wpdb->query(
                $wpdb->prepare(
                        $sql,
                        $ip,
                        $timeWindow,
                        $counterType
                )
        );
    }

    /**
     * Finner antall requests/404 feil for oppgitt IP siste 60 sekunder.
     *     
     * @param string $ip
     * @param int $counterType
     * @return int
     */
    private function getCount(string $ip, int $counterType): int {
        global $wpdb;

        $table = $wpdb->prefix . 'wtb_firewall_rate_counters';

        $timeWindow = intdiv(time(), 30);
        $previousWindow = $timeWindow - 1;

        $sql = "
        SELECT SUM(counter)
        FROM {$table}
        WHERE ip = %s
          AND counter_type = %d
          AND time_window IN (%d, %d)
    ";

        $result = $wpdb->get_var(
                $wpdb->prepare(
                        $sql,
                        $ip,
                        $counterType,
                        $timeWindow,
                        $previousWindow
                )
        );

        return (int) ($result ?? 0);
    }

    /**
     * Sletter alle logførte requests og 404 feil eldre enn 5 minutter.
     */
    public function rateLimitClearLog(): void {
        global $wpdb;

        $table = $wpdb->prefix . 'wtb_firewall_rate_counters';

        // Current time window (30-second buckets)
        $currentWindow = (int) floor(time() / 30);

        // 5 minutes = 300 seconds = 10 windows
        $cutoffWindow = $currentWindow - 10;

        $sql = "
        DELETE FROM {$table}
        WHERE time_window < %d
    ";

        $wpdb->query(
                $wpdb->prepare($sql, $cutoffWindow)
        );
    }
}
