<?php

declare(strict_types=1);

namespace SiteFort\Modules\Firewall\SearchTrust;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use SiteFort\Includes\IpDetector;
use SiteFort\Modules\Firewall\SafeNetwork\SafeNetworkRanges;

// Guards automatic IP bans: published-range IPs are always safe, a claimed
// engine bans only on a proven spoof, indeterminate DNS never bans.
final class SearchTrustBanGate {
	/** @var array<string, bool> */
	private static array $memo = [];

	public static function allows_auto_ban( string $ip, ?string $user_agent = null ): bool {
		$ip = SearchTrustCore::normalize_ip( $ip );
		if ( $ip === '' ) {
			return true;
		}

		if ( $user_agent === null ) {
			$user_agent = (string) IpDetector::get_server_value( 'HTTP_USER_AGENT' );
		}

		$memo_key = $ip . '|' . $user_agent;
		if ( ! isset( self::$memo[ $memo_key ] ) ) {
			self::$memo[ $memo_key ] = self::evaluate( $ip, $user_agent );
		}

		return self::$memo[ $memo_key ];
	}

	private static function evaluate( string $ip, string $user_agent ): bool {
		if (
			SafeNetworkRanges::is_ip_in_set( $ip, SafeNetworkRanges::SET_GOOGLEBOT )
			|| SafeNetworkRanges::is_ip_in_set( $ip, SafeNetworkRanges::SET_BINGBOT )
		) {
			return false;
		}

		$engine = SearchTrustCore::get_verified_search_engine_claim( $user_agent );
		if ( $engine === null ) {
			return true;
		}

		$status = ( new SearchTrustRuntimeResolver( [] ) )->classify_claimed_engine( $ip, $engine );

		return $status === SearchTrustDnsVerifier::TRUST_SPOOFED;
	}
}
