"""Pytest configuration and fixtures."""

import pytest
from datetime import datetime, timedelta
import jwt
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend


@pytest.fixture
def rsa_key_pair():
    """Generate RSA key pair for testing."""
    private_key = rsa.generate_private_key(
        public_exponent=65537,
        key_size=2048,
        backend=default_backend()
    )
    public_key = private_key.public_key()

    private_pem = private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.PKCS8,
        encryption_algorithm=serialization.NoEncryption()
    )

    public_pem = public_key.public_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PublicFormat.SubjectPublicKeyInfo
    )

    return {
        "private_key": private_key,
        "public_key": public_key,
        "private_pem": private_pem,
        "public_pem": public_pem,
    }


@pytest.fixture
def jwks_response(rsa_key_pair):
    """Generate JWKS response for testing."""
    from jwt.algorithms import RSAAlgorithm

    public_key_jwk = RSAAlgorithm.to_jwk(rsa_key_pair["public_key"])
    jwk_dict = jwt.api_jwk.PyJWK.from_json(public_key_jwk).key

    return {
        "keys": [
            {
                "kty": "RSA",
                "use": "sig",
                "kid": "test-key-id",
                "n": jwk_dict.get("n"),
                "e": jwk_dict.get("e"),
            }
        ]
    }


@pytest.fixture
def valid_token(rsa_key_pair):
    """Generate a valid JWT token for testing."""
    now = datetime.utcnow()
    payload = {
        "sub": "user-123",
        "tenant_id": "tenant-456",
        "email": "test@example.com",
        "permissions": ["vessels:read", "vessels:write"],
        "roles": ["admin"],
        "exp": int((now + timedelta(hours=1)).timestamp()),
        "iat": int(now.timestamp()),
        "iss": "vikdata",
        "aud": "vikdata-api",
    }

    token = jwt.encode(
        payload,
        rsa_key_pair["private_pem"],
        algorithm="RS256",
        headers={"kid": "test-key-id"}
    )

    return token


@pytest.fixture
def expired_token(rsa_key_pair):
    """Generate an expired JWT token for testing."""
    now = datetime.utcnow()
    payload = {
        "sub": "user-123",
        "tenant_id": "tenant-456",
        "email": "test@example.com",
        "permissions": ["vessels:read"],
        "exp": int((now - timedelta(hours=1)).timestamp()),
        "iat": int((now - timedelta(hours=2)).timestamp()),
        "iss": "vikdata",
        "aud": "vikdata-api",
    }

    token = jwt.encode(
        payload,
        rsa_key_pair["private_pem"],
        algorithm="RS256",
        headers={"kid": "test-key-id"}
    )

    return token


@pytest.fixture
def mock_service_registration():
    """Mock service registration response."""
    return {
        "id": "service-123",
        "name": "test-service",
        "api_key": "test-api-key-456",
        "status": "active",
        "registered_at": datetime.utcnow().isoformat(),
    }


@pytest.fixture
def mock_service():
    """Mock service details."""
    return {
        "id": "service-123",
        "name": "test-service",
        "description": "Test service description",
        "base_url": "https://test-service.example.com",
        "health_url": "https://test-service.example.com/health",
        "status": "active",
        "permissions": ["test:read", "test:write"],
        "registered_at": datetime.utcnow().isoformat(),
        "last_health_check": None,
        "metadata": {},
    }


@pytest.fixture
def mock_health_status():
    """Mock health status response."""
    return {
        "service_id": "service-123",
        "service_name": "test-service",
        "status": "healthy",
        "checks": {
            "database": {"healthy": True},
            "redis": {"healthy": True},
        },
        "timestamp": datetime.utcnow().isoformat(),
        "details": {},
    }
