"""
MNEMOSYNE — Memory & Intelligence General
==========================================
Fires KG extractor + RLM worker agents to ingest content into memory.

Usage:
    from core.generals.mnemosyne import spawn_mnemosyne
    results = spawn_mnemosyne("/mnt/e/genesis-system/hive/progress/session_52_handoff.md")
"""

import json
import uuid
from datetime import datetime, timezone
from pathlib import Path

REPO_ROOT = Path("/mnt/e/genesis-system")
SWARM_PROGRESS_DIR = REPO_ROOT / "data" / "swarm_progress"
HIVE_PROGRESS_DIR = REPO_ROOT / "hive" / "progress"
KG_ENTITIES_DIR = REPO_ROOT / "KNOWLEDGE_GRAPH" / "entities"
KG_AXIOMS_DIR = REPO_ROOT / "KNOWLEDGE_GRAPH" / "axioms"

KG_EXTRACTOR_PROMPT = """You are MNEMOSYNE, the Memory & Intelligence agent for Genesis.

Content to ingest: {content_path}

Your mission: Extract knowledge entities and axioms from this content.

Instructions:
1. Read the content at {content_path}
2. Extract entities: people, companies, products, capabilities, metrics, events
3. Extract axioms: rules, patterns, learnings, best practices discovered
4. Format entities as JSONL (one JSON object per line)
5. Format axioms as JSONL (one JSON object per line)
6. Write entities to: {entities_output}
7. Write axioms to: {axioms_output}

Entity format:
{{"id": "snake_case_id", "type": "entity_type", "name": "Human Name", "description": "...", "source": "filename", "created": "ISO8601", "tags": []}}

Axiom format:
{{"id": "axiom_id", "text": "The learning/rule/pattern", "domain": "domain_area", "confidence": 0.9, "source": "filename", "created": "ISO8601"}}

Focus on extracting ACTIONABLE intelligence relevant to Genesis operations.
"""

ALPHA_EVOLVE_PROMPT = """You are running an ALPHA EVOLVE cycle for Genesis MNEMOSYNE.

Content: {content_path}

Alpha Evolve 4-phase cycle:
1. INGEST: Read and understand all content
2. EXTRACT: Pull out learnings, failures, wins, patterns
3. SYNTHESIZE: Combine with existing KG to find new truths
4. HARDCODE: Write final axioms to KNOWLEDGE_GRAPH/axioms/

Output your synthesis to: {output_file}
"""

RLM_WORKER_PROMPT = """You are a MNEMOSYNE RLM (Reward Learning Model) worker.

Session content: {content_path}

Your task:
1. Extract preference pairs from this session (what worked vs what didn't)
2. Rate quality of decisions made (1-10 scale with reasoning)
3. Identify reward signals for the Genesis reward model
4. Write preference data to: {output_file}

Format: JSON array of preference pairs:
[{{"prompt": "...", "chosen": "...", "rejected": "...", "reward_delta": 0.5}}]
"""


def spawn_mnemosyne(content_to_ingest: str) -> dict:
    """
    Spawn KG + RLM workers to process content into Genesis memory.

    Parameters
    ----------
    content_to_ingest : str
        Path to file or directory to ingest, OR raw text content

    Returns
    -------
    dict with swarm metadata
    """
    SWARM_PROGRESS_DIR.mkdir(parents=True, exist_ok=True)
    HIVE_PROGRESS_DIR.mkdir(parents=True, exist_ok=True)
    KG_ENTITIES_DIR.mkdir(parents=True, exist_ok=True)
    KG_AXIOMS_DIR.mkdir(parents=True, exist_ok=True)

    swarm_id = f"mnemosyne_{uuid.uuid4().hex[:8]}"
    output_dir = HIVE_PROGRESS_DIR / swarm_id
    output_dir.mkdir(parents=True, exist_ok=True)

    content_path = Path(content_to_ingest) if Path(content_to_ingest).exists() else None
    is_file = content_path is not None and content_path.is_file()
    is_dir = content_path is not None and content_path.is_dir()

    # Determine files to process
    files_to_process: list[Path] = []
    if is_file:
        files_to_process = [content_path]
    elif is_dir:
        files_to_process = sorted(content_path.glob("**/*.md"))[:20]  # Max 20
    else:
        # Raw text: write to temp file
        temp_file = output_dir / "raw_input.md"
        temp_file.write_text(content_to_ingest[:50000])  # Max 50K chars
        files_to_process = [temp_file]

    workers_spawned = 0

    for i, file_path in enumerate(files_to_process):
        slug = file_path.stem.replace(" ", "_")[:30]

        # KG Extractor agent
        entities_out = KG_ENTITIES_DIR / f"mnemosyne_{slug}_{swarm_id[:6]}.jsonl"
        axioms_out = KG_AXIOMS_DIR / f"mnemosyne_{slug}_{swarm_id[:6]}.jsonl"
        kg_prompt = KG_EXTRACTOR_PROMPT.format(
            content_path=str(file_path),
            entities_output=str(entities_out),
            axioms_output=str(axioms_out),
        )
        (output_dir / f"kg_extractor_{i+1:02d}_prompt.md").write_text(kg_prompt)

        # Alpha Evolve agent
        ae_output = output_dir / f"alpha_evolve_{i+1:02d}.md"
        ae_prompt = ALPHA_EVOLVE_PROMPT.format(
            content_path=str(file_path),
            output_file=str(ae_output),
        )
        (output_dir / f"alpha_evolve_{i+1:02d}_prompt.md").write_text(ae_prompt)

        # RLM worker agent
        rlm_output = output_dir / f"rlm_prefs_{i+1:02d}.json"
        rlm_prompt = RLM_WORKER_PROMPT.format(
            content_path=str(file_path),
            output_file=str(rlm_output),
        )
        (output_dir / f"rlm_{i+1:02d}_prompt.md").write_text(rlm_prompt)

        workers_spawned += 3  # 3 agents per file
        print(f"[MNEMOSYNE] 3 workers queued for: {file_path.name}")

    swarm_state = {
        "swarm_id": swarm_id,
        "general": "MNEMOSYNE",
        "mission": f"Ingest: {content_to_ingest[:80]}",
        "model": "deepseek/deepseek-chat",
        "agent_count": workers_spawned,
        "files_processed": len(files_to_process),
        "stories_completed": 0,
        "stories_completed_this_hour": 0,
        "status": "running",
        "started_at": datetime.now(timezone.utc).isoformat(),
        "output_dir": str(output_dir),
    }

    state_file = SWARM_PROGRESS_DIR / f"{swarm_id}.json"
    _save_state(state_file, swarm_state)

    print(f"[MNEMOSYNE] Swarm {swarm_id} — {workers_spawned} workers for {len(files_to_process)} files")
    return swarm_state


def spawn(content_to_ingest: str) -> dict:
    """Alias for spawn_mnemosyne — used by genesis_hive.py router."""
    return spawn_mnemosyne(content_to_ingest)


def _save_state(path: Path, state: dict) -> None:
    path.write_text(json.dumps(state, indent=2, default=str))
