"""
Framework Core - Ядро фреймворка
"""

import sys
import logging
from pathlib import Path
from typing import Dict, Any, Optional, List, Callable
from dataclasses import dataclass, field
from abc import ABC, abstractmethod

# Добавляем src в путь для импорта существующих модулей
project_root = Path(__file__).parent.parent
src_path = project_root / "src"
sys.path.insert(0, str(src_path))

@dataclass
class ProcessingContext:
    """Контекст обработки - передается между этапами пайплайна"""
    input_file: Path
    output_file: Optional[Path] = None
    source_language: str = "auto"
    target_language: str = "ru"

    # Промежуточные данные
    audio_file: Optional[Path] = None
    transcription: Optional[str] = None
    translation: Optional[str] = None
    timestamps: Optional[List] = None

    # Метаданные
    metadata: Dict[str, Any] = field(default_factory=dict)
    settings: Dict[str, Any] = field(default_factory=dict)

    # Колбэки
    progress_callback: Optional[Callable] = None
    log_callback: Optional[Callable] = None

class FrameworkComponent(ABC):
    """Базовый класс для всех компонентов фреймворка"""

    def __init__(self, name: str, config: Dict[str, Any] = None):
        self.name = name
        self.config = config or {}
        self.logger = logging.getLogger(f"framework.{name}")

    @abstractmethod
    def process(self, context: ProcessingContext) -> ProcessingContext:
        """Обработка контекста"""
        pass

    def validate_config(self) -> bool:
        """Валидация конфигурации компонента"""
        return True

    def initialize(self) -> bool:
        """Инициализация компонента"""
        return self.validate_config()

class FrameworkCore:
    """Ядро фреймворка - управляет компонентами и их взаимодействием"""

    def __init__(self, config: Dict[str, Any] = None):
        self.config = config or {}
        self.components: Dict[str, FrameworkComponent] = {}
        self.pipelines: Dict[str, 'ProcessingPipeline'] = {}
        self.logger = logging.getLogger("framework.core")

        # Настройка логирования
        self._setup_logging()

    def _setup_logging(self):
        """Настройка системы логирования"""
        log_level = self.config.get('log_level', 'INFO')
        logging.basicConfig(
            level=getattr(logging, log_level),
            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
        )

    def register_component(self, component: FrameworkComponent) -> 'FrameworkCore':
        """Регистрация компонента в фреймворке"""
        if not component.initialize():
            raise ValueError(f"Failed to initialize component: {component.name}")

        self.components[component.name] = component
        self.logger.info(f"Registered component: {component.name}")
        return self

    def get_component(self, name: str) -> Optional[FrameworkComponent]:
        """Получение компонента по имени"""
        return self.components.get(name)

    def register_pipeline(self, name: str, pipeline: 'ProcessingPipeline') -> 'FrameworkCore':
        """Регистрация пайплайна обработки"""
        self.pipelines[name] = pipeline
        self.logger.info(f"Registered pipeline: {name}")
        return self

    def get_pipeline(self, name: str) -> Optional['ProcessingPipeline']:
        """Получение пайплайна по имени"""
        return self.pipelines.get(name)

    def list_components(self) -> List[str]:
        """Список зарегистрированных компонентов"""
        return list(self.components.keys())

    def list_pipelines(self) -> List[str]:
        """Список зарегистрированных пайплайнов"""
        return list(self.pipelines.keys())

# Декораторы для упрощения создания компонентов
def framework_component(name: str, config: Dict[str, Any] = None):
    """Декоратор для создания компонента из функции"""
    def decorator(func):
        class FunctionComponent(FrameworkComponent):
            def process(self, context: ProcessingContext) -> ProcessingContext:
                return func(context)

        return FunctionComponent(name, config)
    return decorator

def requires_components(*component_names):
    """Декоратор для указания зависимостей компонента"""
    def decorator(cls):
        cls._required_components = component_names
        return cls
    return decorator