import typing

from .core import RequestOptions
from .speech_engine.client import AsyncSpeechEngineClient as AutogeneratedAsyncSpeechEngineClient
from .speech_engine.client import SpeechEngineClient as AutogeneratedSpeechEngineClient
from .speech_engine.resource import SpeechEngineResource
from .types.agent_call_limits import AgentCallLimits
from .types.asr_conversational_config import AsrConversationalConfig
from .types.base_turn_config import BaseTurnConfig
from .types.conversation_config_input import ConversationConfigInput
from .types.privacy_config_input import PrivacyConfigInput
from .types.speech_engine_config import SpeechEngineConfig
from .types.speech_engine_conversation_initiation_client_data_config import SpeechEngineConversationInitiationClientDataConfig
from .types.tts_conversational_config_input import TtsConversationalConfigInput

OMIT = typing.cast(typing.Any, ...)


class SpeechEngineClient(AutogeneratedSpeechEngineClient):
    """Extends the generated SpeechEngineClient with WebSocket server integration."""

    def create(  # type: ignore[override]
        self,
        *,
        speech_engine: SpeechEngineConfig,
        name: typing.Optional[str] = OMIT,
        asr: typing.Optional[AsrConversationalConfig] = OMIT,
        tts: typing.Optional[TtsConversationalConfigInput] = OMIT,
        turn: typing.Optional[BaseTurnConfig] = OMIT,
        conversation: typing.Optional[ConversationConfigInput] = OMIT,
        privacy: typing.Optional[PrivacyConfigInput] = OMIT,
        call_limits: typing.Optional[AgentCallLimits] = OMIT,
        language: typing.Optional[str] = OMIT,
        tags: typing.Optional[typing.Sequence[str]] = OMIT,
        overrides: typing.Optional[SpeechEngineConversationInitiationClientDataConfig] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SpeechEngineResource:
        """Create a Speech Engine resource.

        Makes an API call to create the engine, then returns a
        :class:`SpeechEngineResource` with WebSocket integration methods
        (:meth:`~SpeechEngineResource.serve`,
        :meth:`~SpeechEngineResource.create_session`,
        :meth:`~SpeechEngineResource.verify_request`).
        """
        response = super().create(
            speech_engine=speech_engine,
            name=name,
            asr=asr,
            tts=tts,
            turn=turn,
            conversation=conversation,
            privacy=privacy,
            call_limits=call_limits,
            language=language,
            tags=tags,
            overrides=overrides,
            request_options=request_options,
        )
        return SpeechEngineResource(
            engine_id=response.speech_engine_id,
            client_wrapper=self._raw_client._client_wrapper,
            response=response,
        )

    def get(  # type: ignore[override]
        self,
        speech_engine_id: str,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SpeechEngineResource:
        """Retrieve a Speech Engine resource.

        Makes an API call to validate the engine exists, then returns a
        :class:`SpeechEngineResource` with WebSocket integration methods
        (:meth:`~SpeechEngineResource.serve`,
        :meth:`~SpeechEngineResource.create_session`,
        :meth:`~SpeechEngineResource.verify_request`).
        """
        response = super().get(speech_engine_id, request_options=request_options)
        return SpeechEngineResource(
            engine_id=speech_engine_id,
            client_wrapper=self._raw_client._client_wrapper,
            response=response,
        )

    def update(  # type: ignore[override]
        self,
        speech_engine_id: str,
        *,
        name: typing.Optional[str] = OMIT,
        speech_engine: typing.Optional[SpeechEngineConfig] = OMIT,
        asr: typing.Optional[AsrConversationalConfig] = OMIT,
        tts: typing.Optional[TtsConversationalConfigInput] = OMIT,
        turn: typing.Optional[BaseTurnConfig] = OMIT,
        conversation: typing.Optional[ConversationConfigInput] = OMIT,
        privacy: typing.Optional[PrivacyConfigInput] = OMIT,
        call_limits: typing.Optional[AgentCallLimits] = OMIT,
        language: typing.Optional[str] = OMIT,
        tags: typing.Optional[typing.Sequence[str]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SpeechEngineResource:
        """Update a Speech Engine resource.

        Makes an API call to update the engine, then returns a
        :class:`SpeechEngineResource` with WebSocket integration methods
        (:meth:`~SpeechEngineResource.serve`,
        :meth:`~SpeechEngineResource.create_session`,
        :meth:`~SpeechEngineResource.verify_request`).
        """
        response = super().update(
            speech_engine_id,
            name=name,
            speech_engine=speech_engine,
            asr=asr,
            tts=tts,
            turn=turn,
            conversation=conversation,
            privacy=privacy,
            call_limits=call_limits,
            language=language,
            tags=tags,
            request_options=request_options,
        )
        return SpeechEngineResource(
            engine_id=speech_engine_id,
            client_wrapper=self._raw_client._client_wrapper,
            response=response,
        )


class AsyncSpeechEngineClient(AutogeneratedAsyncSpeechEngineClient):
    """Extends the generated AsyncSpeechEngineClient with WebSocket server integration."""

    async def create(  # type: ignore[override]
        self,
        *,
        speech_engine: SpeechEngineConfig,
        name: typing.Optional[str] = OMIT,
        asr: typing.Optional[AsrConversationalConfig] = OMIT,
        tts: typing.Optional[TtsConversationalConfigInput] = OMIT,
        turn: typing.Optional[BaseTurnConfig] = OMIT,
        conversation: typing.Optional[ConversationConfigInput] = OMIT,
        privacy: typing.Optional[PrivacyConfigInput] = OMIT,
        call_limits: typing.Optional[AgentCallLimits] = OMIT,
        language: typing.Optional[str] = OMIT,
        tags: typing.Optional[typing.Sequence[str]] = OMIT,
        overrides: typing.Optional[SpeechEngineConversationInitiationClientDataConfig] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SpeechEngineResource:
        """Create a Speech Engine resource.

        Makes an API call to create the engine, then returns a
        :class:`SpeechEngineResource` with WebSocket integration methods
        (:meth:`~SpeechEngineResource.serve`,
        :meth:`~SpeechEngineResource.create_session`,
        :meth:`~SpeechEngineResource.verify_request`).
        """
        response = await super().create(
            speech_engine=speech_engine,
            name=name,
            asr=asr,
            tts=tts,
            turn=turn,
            conversation=conversation,
            privacy=privacy,
            call_limits=call_limits,
            language=language,
            tags=tags,
            overrides=overrides,
            request_options=request_options,
        )
        return SpeechEngineResource(
            engine_id=response.speech_engine_id,
            client_wrapper=self._raw_client._client_wrapper,
            response=response,
        )

    async def get(  # type: ignore[override]
        self,
        speech_engine_id: str,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SpeechEngineResource:
        """Retrieve a Speech Engine resource.

        Makes an API call to validate the engine exists, then returns a
        :class:`SpeechEngineResource` with WebSocket integration methods
        (:meth:`~SpeechEngineResource.serve`,
        :meth:`~SpeechEngineResource.create_session`,
        :meth:`~SpeechEngineResource.verify_request`).
        """
        response = await super().get(speech_engine_id, request_options=request_options)
        return SpeechEngineResource(
            engine_id=speech_engine_id,
            client_wrapper=self._raw_client._client_wrapper,
            response=response,
        )

    async def update(  # type: ignore[override]
        self,
        speech_engine_id: str,
        *,
        name: typing.Optional[str] = OMIT,
        speech_engine: typing.Optional[SpeechEngineConfig] = OMIT,
        asr: typing.Optional[AsrConversationalConfig] = OMIT,
        tts: typing.Optional[TtsConversationalConfigInput] = OMIT,
        turn: typing.Optional[BaseTurnConfig] = OMIT,
        conversation: typing.Optional[ConversationConfigInput] = OMIT,
        privacy: typing.Optional[PrivacyConfigInput] = OMIT,
        call_limits: typing.Optional[AgentCallLimits] = OMIT,
        language: typing.Optional[str] = OMIT,
        tags: typing.Optional[typing.Sequence[str]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SpeechEngineResource:
        """Update a Speech Engine resource.

        Makes an API call to update the engine, then returns a
        :class:`SpeechEngineResource` with WebSocket integration methods
        (:meth:`~SpeechEngineResource.serve`,
        :meth:`~SpeechEngineResource.create_session`,
        :meth:`~SpeechEngineResource.verify_request`).
        """
        response = await super().update(
            speech_engine_id,
            name=name,
            speech_engine=speech_engine,
            asr=asr,
            tts=tts,
            turn=turn,
            conversation=conversation,
            privacy=privacy,
            call_limits=call_limits,
            language=language,
            tags=tags,
            request_options=request_options,
        )
        return SpeechEngineResource(
            engine_id=speech_engine_id,
            client_wrapper=self._raw_client._client_wrapper,
            response=response,
        )
