"""Tests for JWTHandler token creation and decoding.

These tests do not require a running server or database.
"""

import time
import pytest

SECRET = "test-secret-key-minimum-32-characters-long"


@pytest.fixture
def handler():
    """Return a JWTHandler configured with a test secret."""
    from app.infrastructure.auth.jwt_handler import JWTHandler
    return JWTHandler(secret_key=SECRET, algorithm="HS256", expire_minutes=30)


def test_create_token_returns_string(handler):
    """create_access_token must return a non-empty string."""
    token = handler.create_access_token(user_id="u1", username="alice", role="admin")
    assert isinstance(token, str)
    assert len(token) > 20


def test_decode_token_returns_correct_claims(handler):
    """decode_token must return UserClaims matching the input."""
    token = handler.create_access_token(user_id="u1", username="alice", role="admin")
    claims = handler.decode_token(token)
    assert claims.user_id == "u1"
    assert claims.username == "alice"
    assert claims.role == "admin"


def test_decode_expired_token_raises(handler):
    """decode_token must raise ValueError on an expired token."""
    from app.infrastructure.auth.jwt_handler import JWTHandler
    short_handler = JWTHandler(secret_key=SECRET, algorithm="HS256", expire_minutes=0)
    token = short_handler.create_access_token(user_id="u2", username="bob", role="readonly")
    time.sleep(1)
    with pytest.raises(ValueError, match="expired"):
        short_handler.decode_token(token)


def test_decode_invalid_token_raises(handler):
    """decode_token must raise ValueError for a tampered token."""
    with pytest.raises(ValueError):
        handler.decode_token("not.a.valid.jwt.token")


def test_decode_wrong_secret_raises():
    """decode_token must raise ValueError when signed with a different secret."""
    from app.infrastructure.auth.jwt_handler import JWTHandler
    creator = JWTHandler(secret_key=SECRET, algorithm="HS256", expire_minutes=60)
    verifier = JWTHandler(secret_key="wrong-secret-key-also-minimum-32-chars", algorithm="HS256", expire_minutes=60)
    token = creator.create_access_token(user_id="u3", username="carol", role="legal")
    with pytest.raises(ValueError):
        verifier.decode_token(token)
