# -*- coding: utf-8 -*-
import logging
import sys
import os
from typing import Any, Dict

from pymsc.core.base_module import BaseModule
from pymsc.core.message_definitions import messages_1553
from pymsc.utils.profiler import monitor_execution

class Bus1553Module(BaseModule):
    """
    Module responsible for 1553 communication.
    Handles internal library aliasing to support moved packages.
    """

    def __init__(self):
        super().__init__(name="Bus1553")
        self.logger = logging.getLogger('PyMsc')
        self.core = None

    def _setup_library_aliasing(self):
        """
        Creates a symbolic link in sys.modules to allow the library 
        to find its own sub-packages using the original name.
        """
        try:
            # 1. Import the sub-package using the current real path
            import pymsc.PyBusMonitor1553 as real_package
            
            # 2. Alias it to the name expected by internal library imports
            # This solves the "No module named 'pybusmonitor1553'" error
            sys.modules['pybusmonitor1553'] = real_package
            
            self.logger.debug("Successfully aliased PyBusMonitor1553 to pybusmonitor1553")
            return True
        except ImportError as e:
            self.logger.error(f"Failed to setup library aliasing: {e}")
            return False

    def initialize(self, config: Dict[str, Any]) -> bool:
        """
        Initializes the low-level core and binds message wrappers.
        """
        # Set up the alias before any other library operation
        if not self._setup_library_aliasing():
            return False
        
        try:
            # Now we can import the core using the aliased name or the real one
            from pybusmonitor1553.core.bus_monitor_core import BusMonitorCore
            self.core = BusMonitorCore()
            self.logger.info("BusMonitorCore instance created.")
        except ImportError as e:
            self.logger.error(f"Critical: Could not load BusMonitorCore. {e}")
            return False

        # Internal library initialization (where it loads messages)
        # Now it will find 'pybusmonitor1553' in sys.modules
        success = self.core.initialize(config)
        
        if not success:
            self.logger.error("BusMonitorCore internal initialization failed.")
            return False

        # Binding our local ctypes structures to the library's message wrappers
        self._bind_messages()
        
        return True

    def _bind_messages(self):
        """
        Connects local message instances to the hardware core wrappers.
        """
        for msg_instance in messages_1553:
            msg_id = msg_instance.message_id
            # Retrieve the wrapper from the hardware core
            wrapper = self.core.get_message(msg_id)
            
            if wrapper:
                msg_instance.bind_to_wrapper(wrapper)
                self.logger.debug(f"Bound message {msg_id} to hardware wrapper.")
            else:
                self.logger.warning(f"Hardware wrapper for {msg_id} not available.")

    @monitor_execution
    def start_session(self) -> None:
        if self.core:
            self.core.start_session()
            self.is_running = True
            self.logger.info("1553 communication session started.")

    @monitor_execution
    def stop_session(self) -> None:
        if self.core:
            self.core.stop_session()
            self.is_running = False
            self.logger.info("1553 communication session stopped.")

    def get_status(self) -> Dict[str, Any]:
        if self.core:
            return self.core.get_status()
        return {"error": "Not initialized"}

    @monitor_execution
    def sync_all_messages(self) -> None:
        """Fetch latest data from the bus for all bound messages."""
        if not self.is_running:
            return
            
        from pymsc.core.message_definitions import update_all_1553_messages
        update_all_1553_messages()