"""Tests for macaroon creation and verification."""

import os
import time

from discourse_toll.macaroon import (
    create_macaroon,
    verify_macaroon,
    encode_macaroon,
    decode_macaroon,
    verify_preimage,
)

SECRET = "aa" * 32
HASH = os.urandom(32).hex()


def test_create_and_verify():
    mac = create_macaroon(SECRET, HASH, expires_at=int(time.time()) + 600)
    valid, err = verify_macaroon(SECRET, mac)
    assert valid, err


def test_wrong_secret():
    mac = create_macaroon(SECRET, HASH)
    valid, _ = verify_macaroon("bb" * 32, mac)
    assert not valid


def test_expired():
    mac = create_macaroon(SECRET, HASH, expires_at=int(time.time()) - 60)
    valid, err = verify_macaroon(SECRET, mac)
    assert not valid
    assert "expired" in err.lower()


def test_endpoint_mismatch():
    mac = create_macaroon(SECRET, HASH, endpoint="/api/comments")
    valid, _ = verify_macaroon(SECRET, mac, endpoint="/api/other")
    assert not valid


def test_method_mismatch():
    mac = create_macaroon(SECRET, HASH, method="POST")
    valid, _ = verify_macaroon(SECRET, mac, method="GET")
    assert not valid


def test_context_mismatch():
    mac = create_macaroon(SECRET, HASH, context_id="thread-1")
    valid, _ = verify_macaroon(SECRET, mac, context_id="thread-2")
    assert not valid


def test_agent_mismatch():
    mac = create_macaroon(SECRET, HASH, agent_id="agent-1")
    valid, _ = verify_macaroon(SECRET, mac, agent_id="agent-2")
    assert not valid


def test_matching_caveats():
    mac = create_macaroon(
        SECRET, HASH,
        expires_at=int(time.time()) + 600,
        endpoint="/api/comments",
        method="POST",
        context_id="t1",
        agent_id="a1",
    )
    valid, err = verify_macaroon(
        SECRET, mac,
        endpoint="/api/comments",
        method="POST",
        context_id="t1",
        agent_id="a1",
    )
    assert valid, err


def test_encode_decode_roundtrip():
    mac = create_macaroon(SECRET, HASH, expires_at=9999999999)
    encoded = encode_macaroon(mac)
    decoded = decode_macaroon(encoded)
    assert decoded == mac


def test_decode_invalid():
    assert decode_macaroon("not-valid!!!") is None


def test_tampered_macaroon():
    mac = create_macaroon(SECRET, HASH)
    mac["caveats"].append("extra = value")
    valid, _ = verify_macaroon(SECRET, mac)
    assert not valid


def test_verify_preimage_valid():
    import hashlib
    preimage = os.urandom(32).hex()
    payment_hash = hashlib.sha256(bytes.fromhex(preimage)).hexdigest()
    assert verify_preimage(preimage, payment_hash)


def test_verify_preimage_invalid():
    assert not verify_preimage("aa" * 32, "bb" * 32)
