import logging
from typing import Optional
import typing

from vocode.streaming.models.synthesizer import (
    AzureSynthesizerConfig,
    CoquiTTSSynthesizerConfig,
    ElevenLabsSynthesizerConfig,
    GTTSSynthesizerConfig,
    GoogleSynthesizerConfig,
    PlayHtSynthesizerConfig,
    RimeSynthesizerConfig,
    StreamElementsSynthesizerConfig,
    SynthesizerConfig,
    SynthesizerType,
)
from vocode.streaming.synthesizer.azure_synthesizer import AzureSynthesizer
from vocode.streaming.synthesizer.eleven_labs_synthesizer import ElevenLabsSynthesizer
from vocode.streaming.synthesizer.google_synthesizer import GoogleSynthesizer
from vocode.streaming.synthesizer.gtts_synthesizer import GTTSSynthesizer
from vocode.streaming.synthesizer.play_ht_synthesizer import PlayHtSynthesizer
from vocode.streaming.synthesizer.rime_synthesizer import RimeSynthesizer
from vocode.streaming.synthesizer.stream_elements_synthesizer import (
    StreamElementsSynthesizer,
)
from vocode.streaming.synthesizer.coqui_tts_synthesizer import CoquiTTSSynthesizer


class SynthesizerFactory:
    def create_synthesizer(
        self,
        synthesizer_config: SynthesizerConfig,
        logger: Optional[logging.Logger] = None,
    ):
        if synthesizer_config.type == SynthesizerType.GOOGLE:
            return GoogleSynthesizer(
                typing.cast(GoogleSynthesizerConfig, synthesizer_config), logger=logger
            )
        elif synthesizer_config.type == SynthesizerType.AZURE:
            return AzureSynthesizer(
                typing.cast(AzureSynthesizerConfig, synthesizer_config), logger=logger
            )
        elif synthesizer_config.type == SynthesizerType.ELEVEN_LABS:
            return ElevenLabsSynthesizer(
                typing.cast(ElevenLabsSynthesizerConfig, synthesizer_config),
                logger=logger,
            )
        elif synthesizer_config.type == SynthesizerType.PLAY_HT:
            return PlayHtSynthesizer(
                typing.cast(PlayHtSynthesizerConfig, synthesizer_config), logger=logger
            )
        elif synthesizer_config.type == SynthesizerType.RIME:
            return RimeSynthesizer(
                typing.cast(RimeSynthesizerConfig, synthesizer_config), logger=logger
            )
        elif synthesizer_config.type == SynthesizerType.GTTS:
            return GTTSSynthesizer(
                typing.cast(GTTSSynthesizerConfig, synthesizer_config), logger=logger
            )
        elif synthesizer_config.type == SynthesizerType.STREAM_ELEMENTS:
            return StreamElementsSynthesizer(
                typing.cast(StreamElementsSynthesizerConfig, synthesizer_config),
                logger=logger,
            )
        elif synthesizer_config.type == SynthesizerType.COQUI_TTS:
            return CoquiTTSSynthesizer(
                typing.cast(CoquiTTSSynthesizerConfig, synthesizer_config),
                logger=logger,
            )
        else:
            raise Exception("Invalid synthesizer config")
