import pytest
import sys
from datetime import timedelta
from unittest.mock import patch

# Force reload to bypass the global mock in conftest
if "session_utils" in sys.modules:
    del sys.modules["session_utils"]
import session_utils

if "auth_utils" in sys.modules:
    del sys.modules["auth_utils"]
import auth_utils
from auth_utils import verify_password, get_password_hash, create_access_token, decode_token

def test_password_hashing():
    pwd = "secret-password"
    hashed = get_password_hash(pwd)
    assert verify_password(pwd, hashed) is True
    assert verify_password("wrong", hashed) is False

def test_token_creation_and_decoding():
    user_data = {"id": 1, "email": "test@example.com", "role": "admin"}
    
    with patch("auth_utils.session_utils") as mock_session:
        mock_session.create_session.return_value = "mock-sid"
        mock_session.validate_session.return_value = True
        
        token = create_access_token(user_data)
        assert token is not None
        
        decoded = decode_token(token)
        assert decoded is not None
        assert decoded["id"] == 1
        assert decoded["email"] == "test@example.com"
        assert decoded["role"] == "admin"
        assert decoded["sid"] == "mock-sid"

def test_decode_invalid_token():
    assert decode_token("invalid.token.here") is None

def test_decode_expired_or_revoked_session():
    user_data = {"id": 1, "sid": "revoked-sid"}
    
    with patch("auth_utils.session_utils") as mock_session:
        mock_session.validate_session.return_value = False
        # We manually create a token that looks valid but whose SID is revoked
        from jose import jwt
        from auth_utils import SECRET_KEY, ALGORITHM
        token = jwt.encode(user_data, SECRET_KEY, algorithm=ALGORITHM)
        
        decoded = decode_token(token)
        assert decoded is None
