
"""
Continuous Evolution Loop
The Heartbeat of Genesis.
Runs an infinite loop of Scout -> Plan -> Evolve cycles using low-cost Gemini Flash agents.
"""

import time
import sys
import os
import signal
from datetime import datetime
import json

# Add root (genesis-system) to path for swarms import
root_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if root_path not in sys.path:
    sys.path.insert(0, root_path)

# Optional swarms import (requires google-generativeai)
try:
    from swarms.genesis_swarm import GenesisSwarm
    SWARM_AVAILABLE = True
except ImportError as e:
    SWARM_AVAILABLE = False
    GenesisSwarm = None
    print(f"[WARN] Swarm unavailable: {e}")

# Hyperdrive integration for multi-agent selection
try:
    from hyperdrive_controller import HyperdriveController, AgentSelector
    HYPERDRIVE_AVAILABLE = True
except ImportError:
    HYPERDRIVE_AVAILABLE = False
    HyperdriveController = None
    AgentSelector = None

def is_unceasing_motion_active():
    path = "E:/genesis-system/config/unceasing_motion.json"
    if os.path.exists(path):
        with open(path, "r") as f:
            config = json.load(f)
            return config.get("unceasing_motion", False)
    return False

class EvolutionLoop:
    def __init__(self):
        # Optional swarm (requires google-generativeai package)
        self.swarm = GenesisSwarm() if SWARM_AVAILABLE and GenesisSwarm else None
        self.running = True

        # Hyperdrive agent selection
        self.agent_selector = AgentSelector() if HYPERDRIVE_AVAILABLE else None

        # Handle graceful shutdown
        signal.signal(signal.SIGINT, self.shutdown)
        signal.signal(signal.SIGTERM, self.shutdown)

    def select_agent(self, task_description: str) -> str:
        """Select optimal agent for task using Hyperdrive."""
        if self.agent_selector:
            classification = self.agent_selector.classify_task(task_description)
            return classification.recommended_agent.value
        return "gemini-2.0-flash"  # Default

    def shutdown(self, signum, frame):
        print("\n\n[Loop] Shutdown signal received. Stopping...")
        self.running = False

    def start(self):
        print(f"\n[Loop] GENESIS EVOLUTION HEARTBEAT STARTED")
        print(f"   Model: Gemini 2.0 Flash Exp")
        budget = self.swarm.daily_budget if self.swarm else "N/A (swarm unavailable)"
        print(f"   Budget: ${budget}/day")
        print(f"   Press Ctrl+C to stop.\n")

        cycle_count = 0

        while self.running:
            try:
                cycle_count += 1
                cycle_start = time.time()

                print(f"\n=== CYCLE {cycle_count} START: {datetime.now().strftime('%H:%M:%S')} ===")

                # Execute the swarm cycle (if available)
                if self.swarm:
                    if is_unceasing_motion_active():
                        print("[Unceasing Motion] Night Mode Active. Prioritizing background chores.")
                        self.swarm.think("unsupervised_evolution")
                    else:
                        self.swarm.run_evolution_cycle()

                    # Check for nervous system triggers
                    self.swarm.trigger_nervous_system("heartbeat", {"cycle": cycle_count})
                else:
                    # Hyperdrive-only mode without swarm
                    print("[Hyperdrive] Running without swarm (install google-generativeai for full features)")

                elapsed = time.time() - cycle_start
                print(f"=== CYCLE {cycle_count} COMPLETE ({elapsed:.2f}s) ===")

                # Sleep between cycles (conserving budget)
                # For aggressive evolution, sleep 60s. For maintenance, sleep 300s.
                sleep_time = 60
                print(f"[Sleep] {sleep_time}s...")
                time.sleep(sleep_time)

            except Exception as e:
                print(f"[Loop] Error: {e}")
                time.sleep(60) # Backoff on error

if __name__ == "__main__":
    loop = EvolutionLoop()
    loop.start()
