from __future__ import annotations

import random

import security.response_handler as rh
from security import ResponseAction, ResponseHandler, ResponseStrategy


def test_get_strategy_banned_blocks():
    handler = ResponseHandler(rng=random.Random(0))
    strategy = handler.get_strategy(10, is_banned=True)
    assert strategy.action == ResponseAction.BLOCK
    assert strategy.delay_seconds == 0
    assert strategy.message == "访问被拒绝"


def test_get_strategy_allow_levels():
    handler = ResponseHandler(rng=random.Random(0))

    s = handler.get_strategy(0)
    assert s.action == ResponseAction.ALLOW
    assert s.delay_seconds == 0
    assert s.captcha_level == 1

    s = handler.get_strategy(21)
    assert s.action == ResponseAction.ALLOW
    assert s.delay_seconds == 0
    assert s.captcha_level == 2


def test_get_strategy_delay_ranges():
    handler = ResponseHandler(rng=random.Random(0))

    s = handler.get_strategy(41)
    assert s.action == ResponseAction.DELAY
    assert 1.0 <= s.delay_seconds <= 2.0

    s = handler.get_strategy(61)
    assert s.action == ResponseAction.DELAY
    assert 2.0 <= s.delay_seconds <= 5.0

    s = handler.get_strategy(81)
    assert s.action == ResponseAction.HONEYPOT
    assert 3.0 <= s.delay_seconds <= 8.0


def test_apply_delay_uses_time_sleep(monkeypatch):
    handler = ResponseHandler(rng=random.Random(0))
    strategy = ResponseStrategy(action=ResponseAction.DELAY, delay_seconds=1.234)

    called = {"count": 0, "seconds": None}

    def fake_sleep(seconds):
        called["count"] += 1
        called["seconds"] = seconds

    monkeypatch.setattr(rh.time, "sleep", fake_sleep)

    handler.apply_delay(strategy)
    assert called["count"] == 1
    assert called["seconds"] == 1.234


def test_get_captcha_requirement():
    handler = ResponseHandler(rng=random.Random(0))

    req = handler.get_captcha_requirement(ResponseStrategy(action=ResponseAction.ALLOW, captcha_level=2))
    assert req == {"required": True, "level": 2}

    req = handler.get_captcha_requirement(ResponseStrategy(action=ResponseAction.BLOCK, captcha_level=2))
    assert req == {"required": False, "level": 2}

