# -*- coding: utf-8 -*-
"""
ARTOS - Advanced Radar Test & Orchestration System
Main entry point for the modular docking GUI.
"""
import sys
import os
import logging
import threading
import time
from datetime import datetime

# Ensure local imports work correctly
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from pymsc.core.bus_1553_module import Bus1553Module
from pymsc.gui.main_docking_window import MainDockingWindow
from pymsc.utils.profiler import print_stats, save_stats_to_csv


# Global flag to control the time update thread
_time_update_running = False
_time_update_thread = None


def update_radar_datetime_periodically(bus_module):
    """
    Background thread that updates msg_a1 date and time every 2 seconds.
    This keeps the radar's mission clock synchronized with system time.
    
    Args:
        bus_module: Bus1553Module instance to access MessageDB
    """
    global _time_update_running
    
    logger = logging.getLogger('ARTOS.TimeSync')
    logger.info("Date/time update thread started (2-second interval)")
    
    # Get MessageDB from BusMonitorCore (the correct instance that's being used)
    try:
        messagedb = bus_module.core._messagedb
        if messagedb is None:
            logger.error("MessageDB not cached in BusMonitorCore - date/time sync disabled")
            return
    except AttributeError as e:
        logger.error(f"Could not access MessageDB from bus_module: {e}")
        return
    
    # Wait for MessageDB to be populated
    max_wait = 10  # seconds
    waited = 0
    while _time_update_running and waited < max_wait:
        all_messages = messagedb.getAllMessages()
        if "A1" in all_messages:
            logger.info(f"A1 message found in MessageDB - starting date/time synchronization")
            break
        time.sleep(0.5)
        waited += 0.5
    
    if waited >= max_wait:
        available_keys = list(messagedb.getAllMessages().keys()) if messagedb else []
        logger.error(f"A1 message not found in MessageDB after {max_wait}s. Available: {available_keys}")
        return
    
    while _time_update_running:
        try:
            now = datetime.now()
            
            # Get the actual A1 message singleton that gets sent to the radar
            all_messages = messagedb.getAllMessages()
            if "A1" not in all_messages:
                logger.warning("A1 message disappeared from MessageDB")
                time.sleep(2.0)
                continue
            
            a1_msg = messagedb.getMessage("A1")
            
            # Update date fields in the actual message structure
            year = now.year % 100
            a1_msg.message.date_of_mission.set_year_of_mission(year)
            a1_msg.message.date_of_mission.set_month_of_mission(now.month)
            a1_msg.message.date_of_mission.set_day_of_mission(now.day)
            
            # Update time field: seconds since midnight divided by 2 (LSB = 2s)
            seconds_since_midnight = now.hour * 3600 + now.minute * 60 + now.second
            a1_msg.message.time_of_mission.set(seconds_since_midnight // 2)
            
            # The message will be sent automatically by the periodic frame sender
            
        except Exception as e:
            logger.error(f"Error updating date/time: {e}", exc_info=True)
        
        # Sleep for 2 seconds before next update
        time.sleep(2.0)
    
    logger.info("Date/time update thread stopped")


def main():
    """
    ARTOS Application Entry Point.
    Initializes the 1553 bus module and launches the modular docking GUI.
    """
    # Create logs directory first
    os.makedirs('logs', exist_ok=True)
    
    # Setup basic logging
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        handlers=[
            logging.FileHandler('logs/artos.log'),
            logging.StreamHandler()
        ]
    )
    logger = logging.getLogger('ARTOS')
    logger.info("=" * 60)
    logger.info("Starting ARTOS - Advanced Radar Test & Orchestration System")
    logger.info("=" * 60)
    
    try:
        # Initialize the 1553 bus module
        logger.info("Initializing Bus 1553 Module...")
        bus_module = Bus1553Module()
        
        # Configure bus communication
        config = {
            'udp_send_ip': '127.0.0.1',
            'udp_send_port': 51553,
            'udp_recv_ip': '0.0.0.0',
            'udp_recv_port': 61553
        }
        
        if bus_module.initialize(config):
            logger.info("Bus 1553 Module initialized successfully.")
        else:
            logger.warning("Bus 1553 Module initialization returned False.")
        
        # Start 1553 communication session automatically
        logger.info("Starting 1553 Bus communication session...")
        bus_module.start_session()
        logger.info("1553 Bus session started - ready to communicate with radar.")
        
        # Initialize date and time of mission with current date/time
        logger.info("Setting current date and time in mission parameters...")
        
        # Wait a moment for MessageDB to be fully populated
        time.sleep(0.5)
        
        try:
            # Get MessageDB from BusMonitorCore (the correct instance that's being used)
            messagedb = bus_module.core._messagedb
            if messagedb is None:
                logger.warning("MessageDB not cached in BusMonitorCore")
                logger.info("Date/time will be set by periodic update thread once MessageDB is available")
            else:
                # Check if A1 message exists in MessageDB
                all_messages = messagedb.getAllMessages()
                if "A1" not in all_messages:
                    logger.warning(f"A1 message not yet in MessageDB. Available messages: {list(all_messages.keys())}")
                    logger.info("Date/time will be set by periodic update thread once A1 is available")
                else:
                    now = datetime.now()
                    
                    # Get the actual A1 message singleton that gets sent to the radar
                    a1_msg = messagedb.getMessage("A1")
                    
                    # Set date: year (last 2 digits), month, day
                    year = now.year % 100  # Last 2 digits (e.g., 2026 -> 26)
                    a1_msg.message.date_of_mission.set_year_of_mission(year)
                    a1_msg.message.date_of_mission.set_month_of_mission(now.month)
                    a1_msg.message.date_of_mission.set_day_of_mission(now.day)
                    
                    # Set time: seconds since midnight divided by 2 (LSB = 2s)
                    seconds_since_midnight = now.hour * 3600 + now.minute * 60 + now.second
                    a1_msg.message.time_of_mission.set(seconds_since_midnight // 2)
                    
                    logger.info(f"Mission date/time set to: {now.strftime('%Y-%m-%d %H:%M:%S')}")
                    logger.info(f"  - Year: {year}, Month: {now.month}, Day: {now.day}")
                    logger.info(f"  - Time value (secs//2): {seconds_since_midnight // 2}")
        except Exception as e:
            logger.error(f"Failed to initialize date/time: {e}", exc_info=True)
        
        # Start periodic date/time update thread (every 2 seconds)
        # This keeps msg_a1 (Radar Settings) date/time synchronized with system time
        global _time_update_running, _time_update_thread
        _time_update_running = True
        _time_update_thread = threading.Thread(
            target=update_radar_datetime_periodically,
            args=(bus_module,),  # Pass bus_module to access MessageDB
            daemon=True,
            name="RadarTimeSync"
        )
        _time_update_thread.start()
        logger.info("Started periodic date/time synchronization (msg_a1, every 2 seconds)")
        
        # Create and launch the modular docking GUI
        logger.info("Launching ARTOS Docking GUI...")
        app = MainDockingWindow(bus_module)
        
        # Start widget refresh loops to display live data
        logger.info("Starting GUI refresh loops...")
        app._start_refresh()
        logger.info("GUI refresh active - widgets will update automatically.")
        
        # Graceful shutdown handler
        def shutdown():
            """Cleanup on application exit."""
            logger.info("Shutting down ARTOS...")
            
            # Stop time update thread
            global _time_update_running
            if _time_update_running:
                _time_update_running = False
                logger.info("Stopping date/time synchronization thread...")
                if _time_update_thread and _time_update_thread.is_alive():
                    _time_update_thread.join(timeout=3.0)
            
            # Stop bus session if running
            if bus_module.is_running:
                bus_module.stop_session()
            
            # Export performance metrics
            logger.info("Exporting performance metrics...")
            save_stats_to_csv("performance_report.csv")
            print_stats()
            
            logger.info("ARTOS shutdown complete.")
            app.root.quit()
            app.root.destroy()
        
        app.root.protocol("WM_DELETE_WINDOW", shutdown)
        
        # Start the GUI main loop
        logger.info("ARTOS GUI ready. Starting main loop...")
        app.run()
        
    except Exception as e:
        logger.error(f"Critical error during ARTOS startup: {e}", exc_info=True)
        sys.exit(1)


if __name__ == "__main__":
    main()