"""
Inference API: run policy compliance checks with query, metadata, and additional_metadata only.

Sync and async interfaces. No source, execution_mode, app_id, or email_id.
"""

from typing import Any

from inhibitor.models import InferenceRequest, InferenceResponse


class InferenceAPI:
    """
    Sync API for the /v1/inference endpoint.

    Use via :attr:`InhibitorClient.inference`. Accepts only query, metadata,
    and additional_metadata.
    """

    def __init__(self, client: "InhibitorClient"):
        self._client = client

    def query(
        self,
        query: str,
        *,
        metadata: dict[str, dict[str, Any]] | None = None,
        additional_metadata: dict[str, dict[str, Any]] | None = None,
    ) -> InferenceResponse:
        """
        Run policy compliance inference on a natural language query.

        :param query: The message or content to evaluate against your policies.
        :param metadata: Optional. Shape: {"key": {"value": "val", "description": "des"}}.
        :param additional_metadata: Optional. Same shape; stored with the log only.
        :return: InferenceResponse with final_decision (ALLOW/MODIFY/BLOCK), explanation, etc.
        """
        request = InferenceRequest(
            query=query,
            metadata=metadata,
            additional_metadata=additional_metadata,
        )
        return self._client._post_inference(request)

    def run(self, request: InferenceRequest) -> InferenceResponse:
        """
        Run inference with a pre-built InferenceRequest.

        Same as :meth:`query` but accepts a request model.
        """
        return self._client._post_inference(request)


class AsyncInferenceAPI(InferenceAPI):
    """Async inference API. Use :meth:`query_async` for non-blocking calls."""

    async def query_async(
        self,
        query: str,
        *,
        metadata: dict[str, dict[str, Any]] | None = None,
        additional_metadata: dict[str, dict[str, Any]] | None = None,
    ) -> InferenceResponse:
        """Run policy compliance inference asynchronously."""
        request = InferenceRequest(
            query=query,
            metadata=metadata,
            additional_metadata=additional_metadata,
        )
        return await self._client._post_inference_async(request)

    async def run_async(self, request: InferenceRequest) -> InferenceResponse:
        """Run inference asynchronously with a pre-built request."""
        return await self._client._post_inference_async(request)
