"""
/mnt/e/genesis-system/core/monitoring/uptime.py

This module provides an uptime monitoring system for Genesis system components.
It periodically checks the availability of specified components and logs their status.
"""

import logging
import time
import importlib
from typing import List, Dict, Callable, Any

# Configure logging
logging.basicConfig(
    level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
)


class UptimeMonitor:
    """
    Monitors the uptime of Genesis system components.
    """

    def __init__(self, components: List[Dict[str, Any]], interval: int = 60):
        """
        Initializes the UptimeMonitor.

        Args:
            components: A list of dictionaries, where each dictionary represents a component
                and contains keys like 'name', 'module', and 'function'. The 'function'
                key should point to a callable that checks the component's availability.
            interval: The interval (in seconds) between uptime checks.  Defaults to 60 seconds.
        """
        self.components = components
        self.interval = interval
        self.running = False  # Flag to control the monitoring loop

    def check_component(self, component: Dict[str, Any]) -> bool:
        """
        Checks the availability of a single component.

        Args:
            component: A dictionary representing the component to check.  Must have 'name', 'module', and 'function' keys.

        Returns:
            True if the component is available, False otherwise.
        """
        name = component["name"]
        module_name = component["module"]
        function_name = component["function"]

        try:
            module = importlib.import_module(module_name)
            check_function: Callable[[], bool] = getattr(module, function_name)  # Type hint for clarity
            is_available = check_function()

            if is_available:
                logging.info(f"Component '{name}' is available.")
                return True
            else:
                logging.warning(f"Component '{name}' is unavailable.")
                return False

        except ImportError as e:
            logging.error(
                f"Failed to import module '{module_name}' for component '{name}': {e}"
            )
            return False
        except AttributeError as e:
            logging.error(
                f"Failed to find function '{function_name}' in module '{module_name}' for component '{name}': {e}"
            )
            return False
        except Exception as e:
            logging.error(f"Error checking component '{name}': {e}")
            return False

    def start(self) -> None:
        """
        Starts the uptime monitoring loop.
        """
        self.running = True
        logging.info("Uptime monitor started.")

        while self.running:
            for component in self.components:
                self.check_component(component)
            time.sleep(self.interval)

        logging.info("Uptime monitor stopped.")

    def stop(self) -> None:
        """
        Stops the uptime monitoring loop.
        """
        self.running = False


if __name__ == "__main__":
    # Example usage:

    # Define components to monitor (replace with actual Genesis components)
    components_to_monitor: List[Dict[str, Any]] = [
        {
            "name": "Database",
            "module": "uptime_mocks",  # Placeholder - replace with actual module
            "function": "check_database_availability",  # Placeholder - replace with actual function
        },
        {
            "name": "API Server",
            "module": "uptime_mocks",  # Placeholder - replace with actual module
            "function": "check_api_server_availability",  # Placeholder - replace with actual function
        },
    ]

    # Create an instance of the UptimeMonitor
    monitor = UptimeMonitor(components=components_to_monitor, interval=10)

    # Start the monitor in a separate thread (optional)
    try:
        monitor.start()
    except KeyboardInterrupt:
        print("Stopping the uptime monitor...")
        monitor.stop()
        print("Uptime monitor stopped.")



# Create a mock module for testing.  Remove this in production
# and replace it with real modules and functions to monitor.
import os
if not os.path.exists("uptime_mocks.py"):  # Avoid clobbering an actual module
    with open("uptime_mocks.py", "w") as f:
        f.write(
            """
import random
def check_database_availability():
    # Simulate database availability with some randomness
    return random.random() > 0.1  # 90% chance of being available

def check_api_server_availability():
    # Simulate API server availability with some randomness
    return random.random() > 0.05  # 95% chance of being available
"""
        )