"""Authentication module for Dangerous Pi API."""
import secrets
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPBasic, HTTPBasicCredentials

from .. import config

security = HTTPBasic()


def verify_credentials(credentials: HTTPBasicCredentials = Depends(security)) -> str:
    """Verify HTTP Basic Auth credentials.

    Args:
        credentials: HTTP Basic credentials from request

    Returns:
        Username if authentication successful

    Raises:
        HTTPException: If authentication fails
    """
    if not config.AUTH_ENABLED:
        return "anonymous"

    if not config.AUTH_PASSWORD:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="AUTH_ENABLED is true but AUTH_PASSWORD is not set",
        )

    # Use constant-time comparison to prevent timing attacks
    is_correct_username = secrets.compare_digest(
        credentials.username.encode("utf-8"),
        config.AUTH_USERNAME.encode("utf-8")
    )
    is_correct_password = secrets.compare_digest(
        credentials.password.encode("utf-8"),
        config.AUTH_PASSWORD.encode("utf-8")
    )

    if not (is_correct_username and is_correct_password):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid credentials",
            headers={"WWW-Authenticate": "Basic"},
        )

    return credentials.username


def get_optional_auth(credentials: HTTPBasicCredentials = Depends(security)) -> str | None:
    """Optional authentication - returns username or None.

    Use this for endpoints where auth is optional based on config.
    """
    if not config.AUTH_ENABLED:
        return None

    try:
        return verify_credentials(credentials)
    except HTTPException:
        return None
