#!/usr/bin/env python3
"""
Genesis Task Executor
=====================
Executes CC-MASTERY-TASKS.md systematically with full autonomous authority.

Workflow:
1. LOAD - Get next pending task
2. DECOMPOSE - Break into subtasks
3. EXECUTE - Invoke skills/tools
4. TEST - Validate implementation
5. ENHANCE - Fix issues, optimize
6. DOCUMENT - Write report, update HANDOFF.md
7. REPORT - Post to Slack
8. NEXT - Continue to next task
"""

import os
import json
from datetime import datetime, timezone
from dataclasses import dataclass, field
from typing import List, Dict, Optional, Any
from enum import Enum


class ExecutionPhase(Enum):
    """Task execution phases."""
    LOAD = "load"
    DECOMPOSE = "decompose"
    EXECUTE = "execute"
    TEST = "test"
    ENHANCE = "enhance"
    DOCUMENT = "document"
    REPORT = "report"
    NEXT = "next"


@dataclass
class Subtask:
    """A subtask within a mastery task."""
    subtask_id: str
    description: str
    status: str = "pending"
    skill_required: Optional[str] = None
    result: Optional[str] = None
    started_at: Optional[str] = None
    completed_at: Optional[str] = None


@dataclass
class TaskExecution:
    """Tracks execution of a mastery task."""
    task_number: int
    task_name: str
    phase: ExecutionPhase = ExecutionPhase.LOAD
    subtasks: List[Subtask] = field(default_factory=list)
    started_at: Optional[str] = None
    completed_at: Optional[str] = None
    report: Optional[str] = None
    success: bool = False


class TaskExecutor:
    """
    Executes mastery tasks autonomously.

    Authority: L4 (Full Autonomous Evolution)
    """

    STATE_FILE = "/mnt/e/genesis-system/config/task_executor_state.json"
    REPORTS_DIR = "/mnt/e/genesis-system/mastery-reports"

    # Task decomposition templates
    TASK_DECOMPOSITIONS = {
        6: [  # LangChain Core Patterns
            ("Research LangChain documentation", "research"),
            ("Implement chain patterns", None),
            ("Implement agent patterns", None),
            ("Implement retriever patterns", None),
            ("Implement memory patterns", None),
            ("Document useful vs bloat", None),
            ("Test LCEL coordination", "test"),
            ("Identify bottlenecks", None),
            ("Write mastery report", None),
        ],
        7: [  # LangGraph Multi-Agent
            ("Research LangGraph architecture", "research"),
            ("Build first multi-agent system", None),
            ("Build second architecture", None),
            ("Build third architecture", None),
            ("Implement state machines", None),
            ("Test human-in-the-loop", "test"),
            ("Compare with custom orchestration", None),
            ("Write mastery report", None),
        ],
        8: [  # RAG Pattern Mastery
            ("Research RAG variations", "research"),
            ("Implement naive RAG", None),
            ("Implement HyDE RAG", None),
            ("Implement fusion RAG", None),
            ("Implement agentic RAG", None),
            ("Implement corrective RAG", None),
            ("Benchmark retrieval accuracy", "test"),
            ("Build production RAG", None),
            ("Write mastery report", None),
        ],
        11: [  # MCP Server Catalog
            ("List all Docker MCP servers", None),
            ("Document filesystem servers", None),
            ("Document database servers", None),
            ("Document API servers", None),
            ("Document dev tools", None),
            ("Categorize by use case", None),
            ("Identify gaps for custom", None),
            ("Write catalog report", None),
        ],
    }

    def __init__(self):
        self.current_execution: Optional[TaskExecution] = None
        self._load_state()

    def _load_state(self) -> None:
        """Load persisted executor state."""
        if os.path.exists(self.STATE_FILE):
            try:
                with open(self.STATE_FILE) as f:
                    state = json.load(f)
                    if state.get("current_task"):
                        self.current_execution = TaskExecution(
                            task_number=state["current_task"]["number"],
                            task_name=state["current_task"]["name"],
                            phase=ExecutionPhase(state["current_task"].get("phase", "load"))
                        )
            except:
                pass

    def _save_state(self) -> None:
        """Persist executor state."""
        state = {
            "current_task": None,
            "last_updated": datetime.now(timezone.utc).isoformat()
        }

        if self.current_execution:
            state["current_task"] = {
                "number": self.current_execution.task_number,
                "name": self.current_execution.task_name,
                "phase": self.current_execution.phase.value
            }

        os.makedirs(os.path.dirname(self.STATE_FILE), exist_ok=True)
        with open(self.STATE_FILE, 'w') as f:
            json.dump(state, f, indent=2)

    def load_task(self, task_number: int, task_name: str) -> TaskExecution:
        """Load a task for execution."""
        self.current_execution = TaskExecution(
            task_number=task_number,
            task_name=task_name,
            started_at=datetime.now(timezone.utc).isoformat()
        )
        self._save_state()
        return self.current_execution

    def decompose_task(self) -> List[Subtask]:
        """Decompose current task into subtasks."""
        if not self.current_execution:
            return []

        task_num = self.current_execution.task_number
        decomposition = self.TASK_DECOMPOSITIONS.get(task_num, [])

        subtasks = []
        for i, (desc, skill) in enumerate(decomposition):
            subtask = Subtask(
                subtask_id=f"st_{task_num}_{i+1:02d}",
                description=desc,
                skill_required=skill
            )
            subtasks.append(subtask)

        self.current_execution.subtasks = subtasks
        self.current_execution.phase = ExecutionPhase.DECOMPOSE
        self._save_state()

        return subtasks

    def execute_subtask(self, subtask_id: str) -> Dict[str, Any]:
        """Execute a specific subtask."""
        if not self.current_execution:
            return {"error": "No task loaded"}

        for subtask in self.current_execution.subtasks:
            if subtask.subtask_id == subtask_id:
                subtask.status = "in_progress"
                subtask.started_at = datetime.now(timezone.utc).isoformat()
                self._save_state()

                return {
                    "subtask_id": subtask_id,
                    "description": subtask.description,
                    "skill_required": subtask.skill_required,
                    "status": "in_progress"
                }

        return {"error": f"Subtask {subtask_id} not found"}

    def complete_subtask(self, subtask_id: str, result: str = "") -> bool:
        """Mark a subtask as complete."""
        if not self.current_execution:
            return False

        for subtask in self.current_execution.subtasks:
            if subtask.subtask_id == subtask_id:
                subtask.status = "complete"
                subtask.completed_at = datetime.now(timezone.utc).isoformat()
                subtask.result = result
                self._save_state()
                return True

        return False

    def advance_phase(self) -> ExecutionPhase:
        """Advance to next execution phase."""
        if not self.current_execution:
            return ExecutionPhase.LOAD

        phase_order = [
            ExecutionPhase.LOAD,
            ExecutionPhase.DECOMPOSE,
            ExecutionPhase.EXECUTE,
            ExecutionPhase.TEST,
            ExecutionPhase.ENHANCE,
            ExecutionPhase.DOCUMENT,
            ExecutionPhase.REPORT,
            ExecutionPhase.NEXT,
        ]

        current_idx = phase_order.index(self.current_execution.phase)
        if current_idx < len(phase_order) - 1:
            self.current_execution.phase = phase_order[current_idx + 1]
            self._save_state()

        return self.current_execution.phase

    def complete_task(self, report: str) -> bool:
        """Complete the current task."""
        if not self.current_execution:
            return False

        self.current_execution.completed_at = datetime.now(timezone.utc).isoformat()
        self.current_execution.report = report
        self.current_execution.success = True
        self.current_execution.phase = ExecutionPhase.NEXT

        # Save report to file
        os.makedirs(self.REPORTS_DIR, exist_ok=True)
        report_file = os.path.join(
            self.REPORTS_DIR,
            f"task_{self.current_execution.task_number:02d}_report.md"
        )
        with open(report_file, 'w') as f:
            f.write(report)

        self._save_state()
        return True

    def get_execution_status(self) -> Dict[str, Any]:
        """Get current execution status."""
        if not self.current_execution:
            return {"status": "idle", "message": "No task in progress"}

        completed = sum(1 for st in self.current_execution.subtasks if st.status == "complete")
        total = len(self.current_execution.subtasks)

        return {
            "task_number": self.current_execution.task_number,
            "task_name": self.current_execution.task_name,
            "phase": self.current_execution.phase.value,
            "subtasks_complete": completed,
            "subtasks_total": total,
            "progress_percent": (completed / total * 100) if total > 0 else 0,
            "started_at": self.current_execution.started_at,
            "success": self.current_execution.success
        }

    def generate_slack_report(self) -> str:
        """Generate Slack-formatted progress report."""
        if not self.current_execution:
            return "GENESIS TASK EXECUTOR: Idle - No task in progress"

        status = self.get_execution_status()

        return f"""GENESIS TASK EXECUTOR - PROGRESS REPORT

Task {status['task_number']}: {status['task_name']}
Phase: {status['phase'].upper()}
Progress: {status['subtasks_complete']}/{status['subtasks_total']} ({status['progress_percent']:.0f}%)
Started: {status['started_at']}

Authority: L4 (Full Autonomous)
Status: {'COMPLETE' if status['success'] else 'IN PROGRESS'}"""


# Singleton instance
_executor: Optional[TaskExecutor] = None


def get_task_executor() -> TaskExecutor:
    """Get or create the task executor instance."""
    global _executor
    if _executor is None:
        _executor = TaskExecutor()
    return _executor


if __name__ == "__main__":
    executor = get_task_executor()
    print(executor.get_execution_status())
