import threading

import pytest

import heal_check
from heal_check.exceptions import CheckError, CheckWarning, WarningTimeoutError


def test_ok(monkeypatch):
    monkeypatch.setattr(heal_check, "check", lambda *_: ["mode"])

    assert heal_check.warning_tolerant_check("url") == ["mode"]


def test_error_untouched(monkeypatch):
    def mock(*_):
        raise CheckError

    monkeypatch.setattr(heal_check, "check", mock)

    with pytest.raises(CheckError):
        heal_check.warning_tolerant_check("url")


def test_timeout(monkeypatch):
    calls = 0

    def mock(*_):
        nonlocal calls
        calls = calls + 1
        raise CheckWarning

    monkeypatch.setattr(heal_check, "check", mock)

    with pytest.raises(WarningTimeoutError) as excinfo:
        heal_check.warning_tolerant_check("url", threading.Event(), 0.1, 0.25)

    assert isinstance(excinfo.value.warning, CheckWarning)
    assert calls == 3


def test_warning_then_ok(monkeypatch):
    calls = 0

    def mock(*_):
        nonlocal calls
        calls = calls + 1

        if calls < 3:
            raise CheckWarning
        else:
            return ["mode"]

    monkeypatch.setattr(heal_check, "check", mock)

    assert heal_check.warning_tolerant_check("url", threading.Event(), 0.1) == ["mode"]


def test_event_externally_set(monkeypatch):
    calls = 0

    def mock(*_):
        nonlocal calls
        calls = calls + 1
        raise CheckWarning

    monkeypatch.setattr(heal_check, "check", mock)

    event = threading.Event()

    timer = threading.Timer(0.25, lambda: event.set())
    timer.start()

    with pytest.raises(WarningTimeoutError):
        heal_check.warning_tolerant_check("url", event, 0.1)

    assert calls == 3

import threading

import pytest

import heal_check
from heal_check.exceptions import CheckError, CheckWarning, WarningTimeoutError


def test_ok(monkeypatch):
    monkeypatch.setattr(heal_check, "check", lambda *_: ["mode"])

    assert heal_check.warning_tolerant_check("url") == ["mode"]


def test_error_untouched(monkeypatch):
    def mock(*_):
        raise CheckError

    monkeypatch.setattr(heal_check, "check", mock)

    with pytest.raises(CheckError):
        heal_check.warning_tolerant_check("url")


def test_timeout(monkeypatch):
    calls = 0

    def mock(*_):
        nonlocal calls
        calls = calls + 1
        raise CheckWarning

    monkeypatch.setattr(heal_check, "check", mock)

    with pytest.raises(WarningTimeoutError) as excinfo:
        heal_check.warning_tolerant_check("url", threading.Event(), 0.1, 0.25)

    assert isinstance(excinfo.value.warning, CheckWarning)
    assert calls == 3


def test_warning_then_ok(monkeypatch):
    calls = 0

    def mock(*_):
        nonlocal calls
        calls = calls + 1

        if calls < 3:
            raise CheckWarning
        else:
            return ["mode"]

    monkeypatch.setattr(heal_check, "check", mock)

    assert heal_check.warning_tolerant_check("url", threading.Event(), 0.1) == ["mode"]


def test_event_externally_set(monkeypatch):
    calls = 0

    def mock(*_):
        nonlocal calls
        calls = calls + 1
        raise CheckWarning

    monkeypatch.setattr(heal_check, "check", mock)

    event = threading.Event()

    timer = threading.Timer(0.25, lambda: event.set())
    timer.start()

    with pytest.raises(WarningTimeoutError):
        heal_check.warning_tolerant_check("url", event, 0.1)

    assert calls == 3
