# This file was auto-generated by Fern from our API Definition.

import typing
import urllib.parse
from json.decoder import JSONDecodeError

import httpx

from .core.api_error import ApiError
from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from .core.jsonable_encoder import jsonable_encoder
from .core.remove_none_from_dict import remove_none_from_dict
from .environment import GigaMlApiEnvironment
from .errors.bad_request_error import BadRequestError
from .types.bad_request_error_body import BadRequestErrorBody
from .types.list_files_response import ListFilesResponse
from .types.log_response import LogResponse

try:
    import pydantic.v1 as pydantic  # type: ignore
except ImportError:
    import pydantic  # type: ignore

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class GigaMlApi:
    def __init__(
        self,
        *,
        base_url: typing.Optional[str] = None,
        environment: GigaMlApiEnvironment = GigaMlApiEnvironment.DEFAULT,
        token: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None,
        timeout: typing.Optional[float] = 60,
        httpx_client: typing.Optional[httpx.Client] = None,
    ):
        self._client_wrapper = SyncClientWrapper(
            base_url=_get_base_url(base_url=base_url, environment=environment),
            token=token,
            httpx_client=httpx.Client(timeout=timeout) if httpx_client is None else httpx_client,
        )

    def list_files(self, *, purpose: typing.Optional[str] = None) -> ListFilesResponse:
        """
        Parameters:
            - purpose: typing.Optional[str]. Only return files with the given purpose.
        ---
        from GigaML.client import GigaMlApi

        client = GigaMlApi(
            token="YOUR_TOKEN",
        )
        client.list_files()
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "files"),
            params=remove_none_from_dict({"purpose": purpose}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ListFilesResponse, _response.json())  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def log(
        self,
        *,
        request_creation_time: typing.Optional[float] = OMIT,
        request_payload: typing.Optional[typing.Any] = OMIT,
        response_payload: typing.Optional[typing.Any] = OMIT,
        total_request_time: typing.Optional[float] = OMIT,
        response_status: typing.Optional[float] = OMIT,
        tags: typing.Optional[typing.List[str]] = OMIT,
    ) -> LogResponse:
        """
        Log a request to any provider

        Parameters:
            - request_creation_time: typing.Optional[float]. Unix timestamp in seconds

            - request_payload: typing.Optional[typing.Any].

            - response_payload: typing.Optional[typing.Any].

            - total_request_time: typing.Optional[float]. Total request time in milli seconds

            - response_status: typing.Optional[float]. HTTP status code of response

            - tags: typing.Optional[typing.List[str]]. Tags to be added to the log
        ---
        from GigaML.client import GigaMlApi

        client = GigaMlApi(
            token="YOUR_TOKEN",
        )
        client.log()
        """
        _request: typing.Dict[str, typing.Any] = {}
        if request_creation_time is not OMIT:
            _request["request_creation_time"] = request_creation_time
        if request_payload is not OMIT:
            _request["request_payload"] = request_payload
        if response_payload is not OMIT:
            _request["response_payload"] = response_payload
        if total_request_time is not OMIT:
            _request["total_request_time"] = total_request_time
        if response_status is not OMIT:
            _request["response_status"] = response_status
        if tags is not OMIT:
            _request["tags"] = tags
        _response = self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v1/log"),
            json=jsonable_encoder(_request),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(LogResponse, _response.json())  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(BadRequestErrorBody, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)


class AsyncGigaMlApi:
    def __init__(
        self,
        *,
        base_url: typing.Optional[str] = None,
        environment: GigaMlApiEnvironment = GigaMlApiEnvironment.DEFAULT,
        token: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None,
        timeout: typing.Optional[float] = 60,
        httpx_client: typing.Optional[httpx.AsyncClient] = None,
    ):
        self._client_wrapper = AsyncClientWrapper(
            base_url=_get_base_url(base_url=base_url, environment=environment),
            token=token,
            httpx_client=httpx.AsyncClient(timeout=timeout) if httpx_client is None else httpx_client,
        )

    async def list_files(self, *, purpose: typing.Optional[str] = None) -> ListFilesResponse:
        """
        Parameters:
            - purpose: typing.Optional[str]. Only return files with the given purpose.
        ---
        from GigaML.client import AsyncGigaMlApi

        client = AsyncGigaMlApi(
            token="YOUR_TOKEN",
        )
        await client.list_files()
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "files"),
            params=remove_none_from_dict({"purpose": purpose}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ListFilesResponse, _response.json())  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def log(
        self,
        *,
        request_creation_time: typing.Optional[float] = OMIT,
        request_payload: typing.Optional[typing.Any] = OMIT,
        response_payload: typing.Optional[typing.Any] = OMIT,
        total_request_time: typing.Optional[float] = OMIT,
        response_status: typing.Optional[float] = OMIT,
        tags: typing.Optional[typing.List[str]] = OMIT,
    ) -> LogResponse:
        """
        Log a request to any provider

        Parameters:
            - request_creation_time: typing.Optional[float]. Unix timestamp in seconds

            - request_payload: typing.Optional[typing.Any].

            - response_payload: typing.Optional[typing.Any].

            - total_request_time: typing.Optional[float]. Total request time in milli seconds

            - response_status: typing.Optional[float]. HTTP status code of response

            - tags: typing.Optional[typing.List[str]]. Tags to be added to the log
        ---
        from GigaML.client import AsyncGigaMlApi

        client = AsyncGigaMlApi(
            token="YOUR_TOKEN",
        )
        await client.log()
        """
        _request: typing.Dict[str, typing.Any] = {}
        if request_creation_time is not OMIT:
            _request["request_creation_time"] = request_creation_time
        if request_payload is not OMIT:
            _request["request_payload"] = request_payload
        if response_payload is not OMIT:
            _request["response_payload"] = response_payload
        if total_request_time is not OMIT:
            _request["total_request_time"] = total_request_time
        if response_status is not OMIT:
            _request["response_status"] = response_status
        if tags is not OMIT:
            _request["tags"] = tags
        _response = await self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v1/log"),
            json=jsonable_encoder(_request),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(LogResponse, _response.json())  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(BadRequestErrorBody, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)


def _get_base_url(*, base_url: typing.Optional[str] = None, environment: GigaMlApiEnvironment) -> str:
    if base_url is not None:
        return base_url
    elif environment is not None:
        return environment.value
    else:
        raise Exception("Please pass in either base_url or environment to construct the client")
