<?php
/**
 * @package Hafenstudios\Wellenbrecher
 */

namespace Hafenstudios\Wellenbrecher\Rules;

use Hafenstudios\Wellenbrecher\Db\SpamLogRepository;
use Hafenstudios\Wellenbrecher\Engine\Context;
use Hafenstudios\Wellenbrecher\Engine\RuleResult;
use Hafenstudios\Wellenbrecher\Support\IpHasher;

defined( 'ABSPATH' ) || exit;

/**
 * Wiederholungstaeter (localdb-Muster): die IP-HMAC matcht einen bereits
 * geblockten oder quarantaenisierten Eintrag in hs_spam_log. Der Abgleich
 * laeuft ueber den HMAC mit dem aktuellen Wochen-Salt; beobachtete
 * (flagged) Eintraege zaehlen NICHT, sonst wuerde der Beobachtungsmodus
 * sich selbst verstaerken. E-Mail-/URL-Abgleich wie bei ASB braeuchte
 * Klartext, den unser Datenmodell bewusst nicht speichert (nur Domain).
 */
class RepeatOffenderRule extends AbstractRule {

	public const ID             = 'repeat_offender';
	public const DEFAULT_POINTS = 30;

	protected SpamLogRepository $log;

	protected IpHasher $hasher;

	/**
	 * @param SpamLogRepository $log    Spam-Log.
	 * @param IpHasher          $hasher IP-HMAC-Helfer.
	 * @param int               $points Punkte.
	 */
	public function __construct( SpamLogRepository $log, IpHasher $hasher, int $points = self::DEFAULT_POINTS ) {
		parent::__construct( $points );
		$this->log    = $log;
		$this->hasher = $hasher;
	}

	public function id(): string {
		return self::ID;
	}

	public function stage(): int {
		return 2;
	}

	public function evaluate( Context $context ): RuleResult {
		$ip = $context->server( 'remote_addr' );
		if ( '' === $ip ) {
			return $this->miss();
		}
		$hmac = $this->hasher->hash( $ip );
		return $this->log->has_spam_match( $hmac ) ? $this->hit() : $this->miss();
	}
}
