"""
Decoder registry for Chapter 10 data types
"""

from typing import Dict, List, Optional, Type
from .base import DataTypeDecoder, DecodedPayload


class DecoderRegistry:
    """Registry for Chapter 10 data type decoders"""
    
    def __init__(self):
        self._decoders: Dict[int, DataTypeDecoder] = {}
        self._decoder_classes: Dict[str, Type[DataTypeDecoder]] = {}
        self._register_default_decoders()
    
    def register_decoder(self, decoder: DataTypeDecoder, data_types: List[int]):
        """Register a decoder for specific data types"""
        for data_type in data_types:
            self._decoders[data_type] = decoder
    
    def register_decoder_class(self, name: str, decoder_class: Type[DataTypeDecoder]):
        """Register a decoder class by name"""
        self._decoder_classes[name] = decoder_class
    
    def get_decoder(self, data_type: int) -> Optional[DataTypeDecoder]:
        """Get decoder for specific data type"""
        return self._decoders.get(data_type)
    
    def decode_payload(self, payload: bytes, ch10_header: Dict[str, any]) -> Optional[DecodedPayload]:
        """Decode payload using appropriate decoder"""
        data_type = ch10_header.get('data_type', 0)
        decoder = self.get_decoder(data_type)
        
        if decoder:
            return decoder.decode(payload, ch10_header)
        
        # Return basic decoded payload if no specific decoder found
        return DecodedPayload(
            data_type=data_type,
            data_type_name=f"Unknown (0x{data_type:02X})",
            format_version=data_type & 0x0F,
            decoded_data={'raw_data': payload.hex()},
            raw_payload=payload,
            errors=[f"No decoder available for data type 0x{data_type:02X}"],
            metadata={'decoder': 'fallback'}
        )
    
    def list_supported_types(self) -> List[int]:
        """List all supported data types"""
        return sorted(self._decoders.keys())
    
    def get_decoder_info(self) -> Dict[int, str]:
        """Get information about registered decoders"""
        return {
            data_type: decoder.__class__.__name__ 
            for data_type, decoder in self._decoders.items()
        }
    
    def _register_default_decoders(self):
        """Register default decoders for known data types"""
        from .tspi_cts import TSPICTSDecoder, ACTTSDecoder, GPSNMEADecoder, EAGACMIDecoder
        from .image import ImageDecoder
        from .uart import UARTDecoder
        from .ieee1394 import IEEE1394Decoder
        from .parallel import ParallelDecoder
        from .ethernet import EthernetDecoder
        from .can_bus import CANBusDecoder
        from .fibre_channel import FibreChannelDecoder
        from .custom_timing import CustomTimingDecoder
        
        # Register custom timing decoder for proprietary formats
        custom_timing_decoder = CustomTimingDecoder()
        # Register for all 0x72xx-0x78xx variants
        custom_timing_types = []
        for base in range(0x72, 0x79):
            for variant in range(0x00, 0x100):
                custom_timing_types.append((base << 8) | variant)
        self.register_decoder(custom_timing_decoder, custom_timing_types)
        
        # Register TSPI/CTS decoders
        tspi_decoder = TSPICTSDecoder()
        self.register_decoder(tspi_decoder, list(range(0x70, 0x78)))
        
        # Register specific TSPI/CTS decoders for better handling
        self.register_decoder(GPSNMEADecoder(), [0x70])
        self.register_decoder(EAGACMIDecoder(), [0x71])
        self.register_decoder(ACTTSDecoder(), [0x72])
        
        # Register Image decoders
        image_decoder = ImageDecoder()
        self.register_decoder(image_decoder, list(range(0x4A, 0x50)))
        
        # Register other decoders
        self.register_decoder(UARTDecoder(), [0x50])
        
        ieee1394_decoder = IEEE1394Decoder()
        self.register_decoder(ieee1394_decoder, [0x58, 0x59])
        
        self.register_decoder(ParallelDecoder(), [0x60])
        
        ethernet_decoder = EthernetDecoder()
        self.register_decoder(ethernet_decoder, [0x68, 0x69])
        
        self.register_decoder(CANBusDecoder(), [0x78])
        self.register_decoder(FibreChannelDecoder(), [0x79])
        
        # Register decoder classes for factory pattern
        self._decoder_classes.update({
            'TSPICTSDecoder': TSPICTSDecoder,
            'ACTTSDecoder': ACTTSDecoder,
            'GPSNMEADecoder': GPSNMEADecoder,
            'EAGACMIDecoder': EAGACMIDecoder,
            'ImageDecoder': ImageDecoder,
            'UARTDecoder': UARTDecoder,
            'IEEE1394Decoder': IEEE1394Decoder,
            'ParallelDecoder': ParallelDecoder,
            'EthernetDecoder': EthernetDecoder,
            'CANBusDecoder': CANBusDecoder,
            'FibreChannelDecoder': FibreChannelDecoder,
            'CustomTimingDecoder': CustomTimingDecoder
        })


# Global decoder registry instance
decoder_registry = DecoderRegistry()