"""Trelent SDK client."""

from __future__ import annotations

import requests

from ._auth import Authenticator
from .resources import ImagesResource, RunsResource, SandboxesResource
from .types import HealthResponse


class Client:
    """Synchronous client for the Trelent Agent API.

    Usage::

        client = Client(
            api_url="https://agents.trelent.com",
            client_id="my-client-id",
            client_secret="my-client-secret",
        )
        images = client.images.list()
        run = client.runs.create(sandbox=images[0].image, prompt="hello")
    """

    def __init__(
        self,
        api_url: str = "https://agents.trelent.com",
        client_id: str | None = None,
        client_secret: str | None = None,
        scope: str | None = None,
    ) -> None:
        self._api_url = api_url.rstrip("/")
        self._session = requests.Session()
        self._session.headers["Content-Type"] = "application/json"

        self._authenticator = self._build_authenticator(client_id, client_secret, scope)

        self.sandboxes = SandboxesResource(self._session, self._api_url, self._authenticator)
        self.images = ImagesResource(self._session, self._api_url, self._authenticator)
        self.runs = RunsResource(self._session, self._api_url, self.sandboxes, self._authenticator)

    def _build_authenticator(
        self,
        client_id: str | None,
        client_secret: str | None,
        scope: str | None,
    ) -> Authenticator | None:
        if client_id is None and client_secret is None:
            return None
        if client_id is None or client_secret is None:
            raise ValueError("client_id and client_secret must both be provided together")
        return Authenticator(
            api_url=self._api_url,
            client_id=client_id,
            client_secret=client_secret,
            scope_override=scope,
        )

    def health(self) -> HealthResponse:
        resp = self._session.get(f"{self._api_url}/health")
        if resp.status_code >= 400:
            resp.raise_for_status()
        return HealthResponse.model_validate(resp.json())

    def close(self) -> None:
        self._session.close()

    def __enter__(self) -> Client:
        return self

    def __exit__(self, *args: object) -> None:
        self.close()
