"""Abstract base class defining the interface for transcription plugins"""

# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/plugin_interface.ipynb.

# %% auto 0
__all__ = ['PluginInterface', 'PluginMeta']

# %% ../nbs/plugin_interface.ipynb 3
from abc import ABC, abstractmethod
import logging
from typing import Optional, Dict, Any, Union, List, Tuple
from pathlib import Path
from dataclasses import dataclass, field
import json
try:
    import jsonschema
    HAS_JSONSCHEMA = True
except ImportError:
    HAS_JSONSCHEMA = False
from .core import AudioData, TranscriptionResult

# %% ../nbs/plugin_interface.ipynb 4
class PluginInterface(ABC):
    """Base interface that all transcription plugins must implement."""
    
    @property
    @abstractmethod
    def name(
        self
    ) -> str:  # The unique identifier for this plugin
        """Unique plugin identifier."""
        pass
    
    @property
    @abstractmethod
    def version(
        self
    ) -> str:  # The semantic version string (e.g., "1.0.0")
        """Plugin version."""
        pass
    
    @property
    @abstractmethod
    def supported_formats(
        self
    ) -> List[str]:  # List of file extensions this plugin can process
        """List of supported audio formats (e.g., ['wav', 'mp3'])."""
        pass
    
    @abstractmethod
    def initialize(
        self,
        config: Optional[Dict[str, Any]] = None  # Configuration dictionary for plugin-specific settings
    ) -> None:
        """Initialize the plugin with configuration."""
        pass
    
    @abstractmethod
    def execute(
        self,
        *args,
        **kwargs
    ) -> Any:  # Returns transcription result or plugin-specific output
        """Transcribe audio to text."""
        pass
    
    @abstractmethod
    def is_available(
        self
    ) -> bool:  # True if all required dependencies are available
        """Check if the plugin's dependencies are available."""
        pass
    
    @abstractmethod
    def get_config_schema(
        self
    ) -> Dict[str, Any]:  # JSON Schema describing configuration options
        """Return JSON Schema describing the plugin's configuration options.
        
        The schema should follow JSON Schema Draft 7 specification.
        This enables automatic UI generation and validation.
        
        Example:
            {
                "type": "object",
                "properties": {
                    "model": {
                        "type": "string",
                        "enum": ["tiny", "base", "small"],
                        "default": "base",
                        "description": "Model size to use"
                    }
                },
                "required": ["model"]
            }
        """
        pass
    
    @abstractmethod
    def get_current_config(
        self
    ) -> Dict[str, Any]:  # Current configuration state
        """Return the current configuration state.
        
        This should return the actual configuration being used by the plugin,
        which may include defaults not explicitly set by the user.
        """
        pass
    
    def validate_config(
        self,
        config: Dict[str, Any]  # Configuration to validate
    ) -> Tuple[bool, Optional[str]]:  # (is_valid, error_message)
        """Validate a configuration dictionary against the schema.
        
        Returns:
            Tuple of (is_valid, error_message).
            If valid, error_message is None.
        """
        schema = self.get_config_schema()
        
        # If jsonschema is available, use it for validation
        if HAS_JSONSCHEMA:
            try:
                jsonschema.validate(instance=config, schema=schema)
                return True, None
            except jsonschema.exceptions.ValidationError as e:
                return False, str(e)
            except Exception as e:
                return False, f"Validation error: {str(e)}"
        else:
            # Basic validation without jsonschema
            try:
                # Check required fields
                required_fields = schema.get("required", [])
                for field in required_fields:
                    if field not in config:
                        return False, f"Missing required field: {field}"
                
                # Check field types if properties are defined
                properties = schema.get("properties", {})
                for key, value in config.items():
                    if key in properties:
                        prop_schema = properties[key]
                        
                        # Check enum values
                        if "enum" in prop_schema and value not in prop_schema["enum"]:
                            return False, f"Invalid value for {key}: {value}. Must be one of {prop_schema['enum']}"
                        
                        # Basic type checking
                        expected_type = prop_schema.get("type")
                        if expected_type:
                            type_map = {
                                "string": str,
                                "number": (int, float),
                                "integer": int,
                                "boolean": bool,
                                "array": list,
                                "object": dict
                            }
                            expected_python_type = type_map.get(expected_type)
                            if expected_python_type and not isinstance(value, expected_python_type):
                                return False, f"Invalid type for {key}: expected {expected_type}, got {type(value).__name__}"
                        
                        # Check numeric constraints
                        if isinstance(value, (int, float)):
                            if "minimum" in prop_schema and value < prop_schema["minimum"]:
                                return False, f"Value for {key} is below minimum: {value} < {prop_schema['minimum']}"
                            if "maximum" in prop_schema and value > prop_schema["maximum"]:
                                return False, f"Value for {key} is above maximum: {value} > {prop_schema['maximum']}"
                
                return True, None
            except Exception as e:
                return False, f"Validation error: {str(e)}"
    
    def get_config_defaults(
        self
    ) -> Dict[str, Any]:  # Default values from schema
        """Extract default values from the configuration schema.
        
        Returns a dictionary of default values for all properties
        that have defaults defined in the schema.
        """
        schema = self.get_config_schema()
        defaults = {}
        
        properties = schema.get("properties", {})
        for key, prop_schema in properties.items():
            if "default" in prop_schema:
                defaults[key] = prop_schema["default"]
        
        return defaults
    
    def cleanup(
        self
    ) -> None:
        """Optional cleanup when plugin is unloaded."""
        pass

# %% ../nbs/plugin_interface.ipynb 6
@dataclass
class PluginMeta:
    """Metadata about a plugin."""
    name: str  # The plugin's unique identifier
    version: str  # The plugin's version string
    description: str = ""  # A brief description of the plugin's functionality
    author: str = ""  # The plugin author's name or organization
    package_name: str = ""  # The Python package name containing the plugin
    instance: Optional[PluginInterface] = None  # The plugin instance
    enabled: bool = True  # Whether the plugin is enabled
