"""
Simple Evolution Loop for Genesis
================================
A lightweight continuous evolution loop that doesn't require heavy dependencies.
Uses the Genesis Execution Layer directly.
"""

import asyncio
import time
import os
import sys
import signal
from datetime import datetime
from pathlib import Path

# Add paths
sys.path.insert(0, str(Path(__file__).parent.parent))

from core.genesis_execution_layer import get_execution_layer, ExecutionMode

# Evolution tasks to cycle through
EVOLUTION_TASKS = [
    "Scout the Genesis codebase for any incomplete TODOs or FIXMEs that need attention",
    "Analyze the KNOWLEDGE_GRAPH entities and identify any missing relationships",
    "Review recent commits and summarize what has been accomplished",
    "Check for any failing tests or type errors in the codebase",
    "Identify optimization opportunities in the core modules",
    "Scan for security vulnerabilities or exposed credentials",
    "Generate a brief status report of Genesis system health",
]

class SimpleEvolutionLoop:
    def __init__(self):
        self.running = True
        self.cycle_count = 0
        self.execution_layer = get_execution_layer()

        # Handle shutdown
        signal.signal(signal.SIGINT, self._shutdown)
        signal.signal(signal.SIGTERM, self._shutdown)

    def _shutdown(self, signum, frame):
        print("\n[Loop] Shutdown signal received...")
        self.running = False

    async def run_cycle(self, task: str):
        """Run a single evolution task."""
        print(f"[Task] {task[:60]}...")

        try:
            result = await self.execution_layer.execute_task(
                task=task,
                context="Genesis System autonomous evolution cycle",
                bypass_gate=True  # Internal system tasks
            )

            if result.success:
                print(f"[OK] Completed - {result.stories_completed} stories, {result.total_tokens} tokens")
            else:
                print(f"[WARN] Issues: {result.errors}")

            return result

        except Exception as e:
            print(f"[ERROR] {e}")
            return None

    async def start(self):
        """Main evolution loop."""
        print("\n" + "="*60)
        print("[Loop] GENESIS SIMPLE EVOLUTION LOOP STARTED")
        print(f"[Loop] Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
        print(f"[Loop] Tasks in rotation: {len(EVOLUTION_TASKS)}")
        print("="*60 + "\n")
        
        # Ensure data directory exists
        os.makedirs("data", exist_ok=True)
        state_file = Path("data/evolution_state.json")
        heartbeat_file = Path("data/evolution_heartbeat")

        task_index = 0
        
        # Load state if exists
        if state_file.exists():
            try:
                import json
                with open(state_file, "r") as f:
                    state = json.load(f)
                    task_index = state.get("task_index", 0)
                    self.cycle_count = state.get("cycle_count", 0)
                print(f"[Loop] Resumed from Cycle {self.cycle_count}, Task Index {task_index}")
            except Exception as e:
                print(f"[WARN] Failed to load state: {e}")

        while self.running:
            try:
                self.cycle_count += 1
                cycle_start = time.time()
                
                # Update heartbeat
                heartbeat_file.touch()
                
                # Save state
                with open(state_file, "w") as f:
                    json.dump({
                        "task_index": task_index,
                        "cycle_count": self.cycle_count,
                        "last_updated": datetime.now().isoformat()
                    }, f)

                print(f"\n=== CYCLE {self.cycle_count} START: {datetime.now().strftime('%H:%M:%S')} ===")
                sys.stdout.flush() # Ensure supervisor sees this immediately

                # Get current task
                task = EVOLUTION_TASKS[task_index % len(EVOLUTION_TASKS)]
                task_index += 1

                # Execute
                await self.run_cycle(task)

                elapsed = time.time() - cycle_start
                print(f"=== CYCLE {self.cycle_count} COMPLETE ({elapsed:.1f}s) ===")
                sys.stdout.flush()

                # Sleep between cycles (60s for active evolution)
                sleep_time = 60
                print(f"[Sleep] {sleep_time}s until next cycle...")
                sys.stdout.flush()

                # Sleep in chunks so we can respond to shutdown
                for _ in range(sleep_time):
                    if not self.running:
                        break
                    await asyncio.sleep(1)
                    # Update heartbeat during sleep so we don't look dead
                    if _ % 10 == 0:
                        heartbeat_file.touch()

            except Exception as e:
                print(f"[ERROR] Cycle failed: {e}")
                sys.stdout.flush()
                await asyncio.sleep(30)  # Backoff on error

        print("\n[Loop] Evolution loop stopped gracefully.")


async def main():
    loop = SimpleEvolutionLoop()
    await loop.start()


if __name__ == "__main__":
    asyncio.run(main())
