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

import contextlib
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.request_options import RequestOptions
from ...core.unchecked_base_model import construct_type
from ..errors.bad_request_error import BadRequestError
from ..errors.internal_server_error import InternalServerError
from ..errors.unauthorized_error import UnauthorizedError
from .types.lightning_request_language import LightningRequestLanguage
from .types.lightning_request_output_format import LightningRequestOutputFormat

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


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

    @contextlib.contextmanager
    def synthesize_lightning_speech(
        self,
        *,
        text: str,
        voice_id: str,
        sample_rate: typing.Optional[int] = OMIT,
        speed: typing.Optional[float] = OMIT,
        language: typing.Optional[LightningRequestLanguage] = OMIT,
        output_format: typing.Optional[LightningRequestOutputFormat] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Iterator[HttpResponse[typing.Iterator[bytes]]]:
        """
        Get speech for given text using the Waves API

        Parameters
        ----------
        text : str
            The text to convert to speech.

        voice_id : str
            The voice identifier to use for speech generation.

        sample_rate : typing.Optional[int]
            The sample rate for the generated audio.

        speed : typing.Optional[float]
            The speed of the generated speech.

        language : typing.Optional[LightningRequestLanguage]
            Determines how numbers are spelled out. If set to 'en', numbers will be read as individual digits in English. If set to 'hi', numbers will be read as individual digits in Hindi.

        output_format : typing.Optional[LightningRequestOutputFormat]
            The format of the output audio.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.

        Returns
        -------
        typing.Iterator[HttpResponse[typing.Iterator[bytes]]]
            Synthesized speech retrieved successfully.
        """
        with self._client_wrapper.httpx_client.stream(
            "api/v1/lightning/get_speech",
            base_url=self._client_wrapper.get_environment().waves,
            method="POST",
            json={
                "text": text,
                "voice_id": voice_id,
                "sample_rate": sample_rate,
                "speed": speed,
                "language": language,
                "output_format": output_format,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        ) as _response:

            def _stream() -> HttpResponse[typing.Iterator[bytes]]:
                try:
                    if 200 <= _response.status_code < 300:
                        _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
                        return HttpResponse(
                            response=_response, data=(_chunk for _chunk in _response.iter_bytes(chunk_size=_chunk_size))
                        )
                    _response.read()
                    if _response.status_code == 400:
                        raise BadRequestError(
                            headers=dict(_response.headers),
                            body=typing.cast(
                                typing.Any,
                                construct_type(
                                    type_=typing.Any,  # type: ignore
                                    object_=_response.json(),
                                ),
                            ),
                        )
                    if _response.status_code == 401:
                        raise UnauthorizedError(
                            headers=dict(_response.headers),
                            body=typing.cast(
                                typing.Any,
                                construct_type(
                                    type_=typing.Any,  # type: ignore
                                    object_=_response.json(),
                                ),
                            ),
                        )
                    if _response.status_code == 500:
                        raise InternalServerError(
                            headers=dict(_response.headers),
                            body=typing.cast(
                                typing.Any,
                                construct_type(
                                    type_=typing.Any,  # 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)

            yield _stream()


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

    @contextlib.asynccontextmanager
    async def synthesize_lightning_speech(
        self,
        *,
        text: str,
        voice_id: str,
        sample_rate: typing.Optional[int] = OMIT,
        speed: typing.Optional[float] = OMIT,
        language: typing.Optional[LightningRequestLanguage] = OMIT,
        output_format: typing.Optional[LightningRequestOutputFormat] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]:
        """
        Get speech for given text using the Waves API

        Parameters
        ----------
        text : str
            The text to convert to speech.

        voice_id : str
            The voice identifier to use for speech generation.

        sample_rate : typing.Optional[int]
            The sample rate for the generated audio.

        speed : typing.Optional[float]
            The speed of the generated speech.

        language : typing.Optional[LightningRequestLanguage]
            Determines how numbers are spelled out. If set to 'en', numbers will be read as individual digits in English. If set to 'hi', numbers will be read as individual digits in Hindi.

        output_format : typing.Optional[LightningRequestOutputFormat]
            The format of the output audio.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.

        Returns
        -------
        typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]
            Synthesized speech retrieved successfully.
        """
        async with self._client_wrapper.httpx_client.stream(
            "api/v1/lightning/get_speech",
            base_url=self._client_wrapper.get_environment().waves,
            method="POST",
            json={
                "text": text,
                "voice_id": voice_id,
                "sample_rate": sample_rate,
                "speed": speed,
                "language": language,
                "output_format": output_format,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        ) as _response:

            async def _stream() -> AsyncHttpResponse[typing.AsyncIterator[bytes]]:
                try:
                    if 200 <= _response.status_code < 300:
                        _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
                        return AsyncHttpResponse(
                            response=_response,
                            data=(_chunk async for _chunk in _response.aiter_bytes(chunk_size=_chunk_size)),
                        )
                    await _response.aread()
                    if _response.status_code == 400:
                        raise BadRequestError(
                            headers=dict(_response.headers),
                            body=typing.cast(
                                typing.Any,
                                construct_type(
                                    type_=typing.Any,  # type: ignore
                                    object_=_response.json(),
                                ),
                            ),
                        )
                    if _response.status_code == 401:
                        raise UnauthorizedError(
                            headers=dict(_response.headers),
                            body=typing.cast(
                                typing.Any,
                                construct_type(
                                    type_=typing.Any,  # type: ignore
                                    object_=_response.json(),
                                ),
                            ),
                        )
                    if _response.status_code == 500:
                        raise InternalServerError(
                            headers=dict(_response.headers),
                            body=typing.cast(
                                typing.Any,
                                construct_type(
                                    type_=typing.Any,  # 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)

            yield await _stream()
