from abc import ABC, abstractmethod
from typing import Optional


class PermanentError(Exception):
    """Error that should not be retried (e.g., URL fetch failure)."""
    pass


class APIProvider(ABC):
    @abstractmethod
    def transcribe(
        self,
        model_variant: str,
        audio_file_path: Optional[str],
        sample: dict,
        use_url: bool = False,
        language: str = "en",
        prompt: Optional[str] = None,
    ) -> str:
        """Transcribe audio and return the text."""
        ...


_REGISTRY: dict[str, type[APIProvider]] = {}


def register(prefix: str):
    """Decorator to register a provider class under a model prefix."""
    def decorator(cls: type[APIProvider]):
        _REGISTRY[prefix] = cls
        return cls
    return decorator


def get_provider(model_name: str) -> tuple[APIProvider, str]:
    """Look up provider by model_name prefix, return (provider_instance, variant)."""
    for prefix, cls in _REGISTRY.items():
        if model_name.startswith(prefix + "/"):
            variant = model_name[len(prefix) + 1:]
            return cls(), variant
    raise ValueError(
        f"No provider registered for model '{model_name}'. "
        f"Known prefixes: {list(_REGISTRY.keys())}"
    )


# Auto-import all provider modules so they register themselves
from . import speechmatics_provider
from . import assemblyai_provider
from . import openai_provider
from . import elevenlabs_provider
from . import revai_provider
from . import aquavoice_provider
from . import zoom_provider
from . import smallest_provider
from . import reson8_provider
from . import microsoft_azure_provider
