from dataclasses import dataclass

from django.conf import settings
from rest_framework import authentication, exceptions


@dataclass(frozen=True)
class ServicePrincipal:
    identifier: str

    @property
    def is_authenticated(self):
        return True

    @property
    def pk(self):
        return self.identifier


class ServiceAPIKeyAuthentication(authentication.BaseAuthentication):
    keyword = "Bearer"

    def authenticate(self, request):
        expected_api_key = settings.INTERNAL_API_KEY
        provided_api_key = self._extract_token(request)

        if not provided_api_key:
            raise exceptions.AuthenticationFailed("Missing API key.")

        if provided_api_key != expected_api_key:
            raise exceptions.AuthenticationFailed("Invalid API key.")

        return (ServicePrincipal(identifier="internal-service"), provided_api_key)

    def authenticate_header(self, request):
        return self.keyword

    def _extract_token(self, request):
        auth_header = authentication.get_authorization_header(request).decode("utf-8")
        if auth_header.startswith(f"{self.keyword} "):
            return auth_header.removeprefix(f"{self.keyword} ").strip()

        return request.headers.get("X-API-Key")
