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

import typing
from json.decoder import JSONDecodeError

from ...core.api_error import ApiError
from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ...core.http_response import AsyncHttpResponse, HttpResponse
from ...core.pydantic_utilities import parse_obj_as
from ...core.request_options import RequestOptions
from ...core.serialization import convert_and_respect_annotation_metadata
from ...errors.bad_request_error import BadRequestError
from ...errors.internal_server_error import InternalServerError
from ...errors.unauthorized_error import UnauthorizedError
from ...types.error import Error
from ...types.refreshed_file import RefreshedFile
from ...types.upload_results import UploadResults
from .types.upload_file_options import UploadFileOptions

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


class RawFileClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def upload(
        self,
        *,
        content_type: str,
        size: int,
        name: typing.Optional[str] = OMIT,
        options: typing.Optional[UploadFileOptions] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[UploadResults]:
        """
        Generate presigned URLs that let you upload files directly to our storage and allow your users to download them securely.

        Parameters
        ----------
        content_type : str
            MIME type of your file. <br>

            Supported file types:
            - Audio: mp3, mp4, mpeg, ogg, aac, webm, wav, 3gpp, amr
            - Video: mp4, mpeg, quicktime, webm, 3gpp, H.264, m4v
            - Image: jpeg, png, gif, bmp, tiff, webp
            - Documents: pdf, csv, rtf, calendar, vcard

        size : int
            Size of your file in bytes. Should be less than 100 MB.

        name : typing.Optional[str]
            Name of your file.

        options : typing.Optional[UploadFileOptions]
            Additional configurations for your file.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[UploadResults]
            Successfully uploaded the file.
        """
        _response = self._client_wrapper.httpx_client.request(
            "tools/files/upload",
            method="POST",
            json={
                "contentType": content_type,
                "size": size,
                "name": name,
                "options": convert_and_respect_annotation_metadata(
                    object_=options, annotation=UploadFileOptions, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UploadResults,
                    parse_obj_as(
                        type_=UploadResults,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def refresh(
        self, *, urls: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[typing.List[RefreshedFile]]:
        """
        Refresh expiring presigned URLs for Pinnacle-hosted files to extend their access time.

        <Callout type="info">
          This only works for presigned download URLs. At this moment, you cannot refresh a presigned upload URL, generate a new one instead.
        </Callout>

        Parameters
        ----------
        urls : typing.Sequence[str]
            Array of file URLs to refresh for extended access. Provided URLs must be presigned URLs (i.e. `https://server.trypinnacle.app/storage/v1/object/sign/...`). Invalid or external URLs will be returned unchanged in the response.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[typing.List[RefreshedFile]]
            Successfully refreshed file URLs.
        """
        _response = self._client_wrapper.httpx_client.request(
            "tools/files/refresh",
            method="POST",
            json={
                "urls": urls,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[RefreshedFile],
                    parse_obj_as(
                        type_=typing.List[RefreshedFile],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


class AsyncRawFileClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def upload(
        self,
        *,
        content_type: str,
        size: int,
        name: typing.Optional[str] = OMIT,
        options: typing.Optional[UploadFileOptions] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[UploadResults]:
        """
        Generate presigned URLs that let you upload files directly to our storage and allow your users to download them securely.

        Parameters
        ----------
        content_type : str
            MIME type of your file. <br>

            Supported file types:
            - Audio: mp3, mp4, mpeg, ogg, aac, webm, wav, 3gpp, amr
            - Video: mp4, mpeg, quicktime, webm, 3gpp, H.264, m4v
            - Image: jpeg, png, gif, bmp, tiff, webp
            - Documents: pdf, csv, rtf, calendar, vcard

        size : int
            Size of your file in bytes. Should be less than 100 MB.

        name : typing.Optional[str]
            Name of your file.

        options : typing.Optional[UploadFileOptions]
            Additional configurations for your file.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[UploadResults]
            Successfully uploaded the file.
        """
        _response = await self._client_wrapper.httpx_client.request(
            "tools/files/upload",
            method="POST",
            json={
                "contentType": content_type,
                "size": size,
                "name": name,
                "options": convert_and_respect_annotation_metadata(
                    object_=options, annotation=UploadFileOptions, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UploadResults,
                    parse_obj_as(
                        type_=UploadResults,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def refresh(
        self, *, urls: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[typing.List[RefreshedFile]]:
        """
        Refresh expiring presigned URLs for Pinnacle-hosted files to extend their access time.

        <Callout type="info">
          This only works for presigned download URLs. At this moment, you cannot refresh a presigned upload URL, generate a new one instead.
        </Callout>

        Parameters
        ----------
        urls : typing.Sequence[str]
            Array of file URLs to refresh for extended access. Provided URLs must be presigned URLs (i.e. `https://server.trypinnacle.app/storage/v1/object/sign/...`). Invalid or external URLs will be returned unchanged in the response.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[typing.List[RefreshedFile]]
            Successfully refreshed file URLs.
        """
        _response = await self._client_wrapper.httpx_client.request(
            "tools/files/refresh",
            method="POST",
            json={
                "urls": urls,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[RefreshedFile],
                    parse_obj_as(
                        type_=typing.List[RefreshedFile],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
