from __future__ import annotations

"""Tests for generic backend utilities used across routes."""

from atlas_portal import rate_limit, utils


def test_rate_limit_allows_when_limit_is_non_positive() -> None:
    assert rate_limit.rate_limit_allow("1.2.3.4", key="access", limit=0, window_sec=60)
    assert rate_limit.rate_limit_allow("1.2.3.4", key="access", limit=-1, window_sec=60)


def test_rate_limit_rejects_after_limit(monkeypatch) -> None:
    monkeypatch.setattr(rate_limit.time, "time", lambda: 100.0)
    assert rate_limit.rate_limit_allow("1.2.3.4", key="access", limit=2, window_sec=60)
    assert rate_limit.rate_limit_allow("1.2.3.4", key="access", limit=2, window_sec=60)
    assert not rate_limit.rate_limit_allow("1.2.3.4", key="access", limit=2, window_sec=60)


def test_random_password_has_requested_length() -> None:
    password = utils.random_password(24)

    assert len(password) == 24
    assert password.isalnum()


def test_best_effort_post_ignores_errors(monkeypatch) -> None:
    calls = []

    class DummyClient:
        def __init__(self, timeout):
            calls.append(timeout)

        def __enter__(self):
            return self

        def __exit__(self, exc_type, exc, tb):
            return False

        def post(self, url, json=None):
            raise RuntimeError("boom")

    monkeypatch.setattr(utils.httpx, "Client", DummyClient)

    utils.best_effort_post("https://example.dev/hook")

    assert calls


def test_best_effort_post_success(monkeypatch) -> None:
    posts = []

    class DummyClient:
        def __init__(self, timeout):
            self.timeout = timeout

        def __enter__(self):
            return self

        def __exit__(self, exc_type, exc, tb):
            return False

        def post(self, url, json=None):
            posts.append((url, json))
            return None

    monkeypatch.setattr(utils.httpx, "Client", DummyClient)

    utils.best_effort_post("https://example.dev/hook")

    assert posts and posts[0][0] == "https://example.dev/hook"


def test_best_effort_post_ignores_empty_url() -> None:
    utils.best_effort_post("")
