"""
Configuration Loader

Loads and validates framework configuration files.
"""

import json
from pathlib import Path
from typing import Dict, Any, List, Optional
from dataclasses import dataclass


@dataclass
class FrameworkConfig:
    """Framework metadata"""
    name: str
    slug: str
    version: str
    description: str
    tagline: str
    icon: str
    hub_port: int


@dataclass
class SystemConfig:
    """System configuration"""
    key: str
    name: str
    slug: str
    title: str
    tagline: str
    port: int
    icon: str


@dataclass
class ComponentConfig:
    """Component configuration"""
    name: str
    title: str
    description: str
    plural: Optional[str] = None
    formula: Optional[str] = None


class ConfigLoader:
    """Loads and parses framework configuration"""

    def __init__(self, config_path: Path):
        self.config_path = Path(config_path)
        self.raw_config: Dict[str, Any] = {}
        self.framework: Optional[FrameworkConfig] = None
        self.systems: List[SystemConfig] = []
        self.components: Dict[str, Dict[str, ComponentConfig]] = {}

    def load(self) -> 'ConfigLoader':
        """Load configuration from file"""
        with open(self.config_path) as f:
            self.raw_config = json.load(f)

        self._parse_framework()
        self._parse_systems()
        self._parse_components()

        return self

    def _parse_framework(self):
        """Parse framework metadata"""
        fw = self.raw_config['framework']
        self.framework = FrameworkConfig(**fw)

    def _parse_systems(self):
        """Parse system configurations"""
        for sys in self.raw_config['systems']:
            self.systems.append(SystemConfig(**sys))

    def _parse_components(self):
        """Parse component configurations"""
        comps = self.raw_config['components']

        # Shared components
        self.components['shared'] = {}
        for key, value in comps.get('shared', {}).items():
            self.components['shared'][key] = ComponentConfig(**value)

        # System-specific components
        for system_key in ['data_flow', 'documentation', 'execution']:
            self.components[system_key] = {}
            for comp_key, comp_value in comps.get(system_key, {}).items():
                self.components[system_key][comp_key] = ComponentConfig(**comp_value)

    def get_system(self, key: str) -> Optional[SystemConfig]:
        """Get system config by key"""
        for sys in self.systems:
            if sys.key == key:
                return sys
        return None

    def get_component(self, system_key: str, component_key: str) -> Optional[ComponentConfig]:
        """Get component config"""
        return self.components.get(system_key, {}).get(component_key)

    def get_shared_component(self, key: str) -> Optional[ComponentConfig]:
        """Get shared component config"""
        return self.components.get('shared', {}).get(key)


def load_config(config_path: str | Path) -> ConfigLoader:
    """Load and validate configuration file"""
    loader = ConfigLoader(config_path)
    return loader.load()


if __name__ == "__main__":
    # Test with pawprint config
    import sys
    config_path = Path(__file__).parent.parent / "pawprint.config.json"

    loader = load_config(config_path)

    print(f"Framework: {loader.framework.name} v{loader.framework.version}")
    print(f"Tagline: {loader.framework.tagline}")
    print(f"\nSystems:")
    for sys in loader.systems:
        print(f"  {sys.icon} {sys.title} ({sys.name}) - {sys.tagline}")

    print(f"\nShared Components:")
    for key, comp in loader.components['shared'].items():
        print(f"  {comp.name} - {comp.description}")
