from http import HTTPStatus
from typing import Annotated, override

from fastapi import Path

from phederation.api.routes.base import BaseRoute
from phederation.models.errors import BaseError
from phederation.models.proofs import DataIntegrityProof
from phederation.utils.base import UrlType, assemble_id_url
from phederation.utils.exceptions import SecurityError


class ErrorMessageProofNotFound(BaseError):
    message: str = "Proof not found"


class ProofRoute(BaseRoute):

    @override
    def setup(self):

        @self.router.get(
            "/proofs/{proof_primary}",
            status_code=HTTPStatus.OK,
            response_model_exclude_none=True,
            responses={
                HTTPStatus.NOT_FOUND: {
                    "model": ErrorMessageProofNotFound,
                    "description": "If the proof with the given primary cannot be found on this instance.",
                }
            },
            tags=["proofs"],
        )
        async def get_proof(  # pyright: ignore[reportUnusedFunction]
            proof_primary: Annotated[str, Path(description="The identifier of the key (without the URL) on this instance.")],
        ) -> DataIntegrityProof:
            """Handle requests for proofs.

            Visibility is not checked here, all proofs are public.
            """
            self.logger.debug(f"Received request for proof primary: {proof_primary}")

            # Return key document with proper JSON-LD context
            proof_id = assemble_id_url(type=UrlType.Proofs, base_url=self.api.settings.domain.base_url, primary=proof_primary)
            proof = await self.api.server.storage.proof.read(id=proof_id)
            if not proof:
                log_message = f"No proof found with primary '{proof_primary}'"
                raise SecurityError(message=log_message, user_facing_message=ErrorMessageProofNotFound().message, status_code=HTTPStatus.NOT_FOUND)

            return proof
