# retoor <retoor@molodetz.nl>

import time
import requests
from tests.conftest import BASE_URL
from devplacepy.database import get_table

JSON = {"Accept": "application/json"}
_counter = [0]


def _signup():
    _counter[0] += 1
    name = f"blk{int(time.time() * 1000)}{_counter[0]}"
    session = requests.Session()
    session.post(
        f"{BASE_URL}/auth/signup",
        data={
            "username": name,
            "email": f"{name}@t.dev",
            "password": "secret123",
            "confirm_password": "secret123",
            "birth_date": "1990-01-01",
            "accept_terms": "1",
        },
        allow_redirects=True,
    )
    return session, name


def _uid(name):
    return get_table("users").find_one(username=name)["uid"]


def _key(name):
    return get_table("users").find_one(username=name)["api_key"]


def _relation(actor_uid, target_uid, kind):
    return get_table("user_relations").count(
        user_uid=actor_uid, target_uid=target_uid, kind=kind, deleted_at=None
    )


def test_block_creates_relation(app_server):
    blocker_session, blocker = _signup()
    _, target = _signup()
    r = blocker_session.post(
        f"{BASE_URL}/block/{target}", allow_redirects=False
    )
    assert r.status_code in (302, 200)
    assert _relation(_uid(blocker), _uid(target), "block") == 1


def test_block_via_api_key_header(app_server):
    blocker_session, blocker = _signup()
    _, target = _signup()
    r = requests.post(
        f"{BASE_URL}/block/{target}",
        headers={"X-API-KEY": _key(blocker)},
        allow_redirects=False,
    )
    assert r.status_code in (302, 200)
    assert _relation(_uid(blocker), _uid(target), "block") == 1


def test_block_is_idempotent(app_server):
    blocker_session, blocker = _signup()
    _, target = _signup()
    blocker_session.post(f"{BASE_URL}/block/{target}", allow_redirects=False)
    blocker_session.post(f"{BASE_URL}/block/{target}", allow_redirects=False)
    assert _relation(_uid(blocker), _uid(target), "block") == 1


def test_self_block_rejected(app_server):
    blocker_session, blocker = _signup()
    blocker_session.post(f"{BASE_URL}/block/{blocker}", allow_redirects=False)
    assert _relation(_uid(blocker), _uid(blocker), "block") == 0


def test_block_nonexistent_user_redirects(app_server):
    blocker_session, _ = _signup()
    r = blocker_session.post(
        f"{BASE_URL}/block/no_such_user_zzz", allow_redirects=False
    )
    assert r.status_code == 302


def test_block_no_credentials_redirects(app_server):
    _, target = _signup()
    r = requests.post(f"{BASE_URL}/block/{target}", allow_redirects=False)
    assert r.status_code == 303


def test_block_invalid_api_key_returns_401(app_server):
    _, target = _signup()
    r = requests.post(
        f"{BASE_URL}/block/{target}",
        headers={"X-API-KEY": "not-a-real-key"},
        allow_redirects=False,
    )
    assert r.status_code == 401


def test_block_recorded_in_audit(seeded_db):
    blocker_session, blocker = _signup()
    blocker_session.post(
        f"{BASE_URL}/block/bob_test", headers=JSON, allow_redirects=False
    )
    admin = requests.Session()
    admin.headers.update({"X-API-KEY": _key("alice_test")})
    data = admin.get(
        f"{BASE_URL}/admin/audit-log",
        headers=JSON,
        params={"event_key": "relation.block"},
    ).json()
    assert any(
        e.get("target_label") == "bob_test" and blocker in (e.get("summary") or "")
        for e in data["entries"]
    )
