#!/usr/bin/env python3
"""
World Build Script for Timmy's Evennia World
Issue #83 — Scaffold the world

Run this script to create the initial world structure:
  python evennia_launcher.py shell -f world/build.py

Or from in-game:
  @py from world.build import build_world; build_world()
"""

from evennia import create_object, search_object
from evennia.utils import create
from typeclasses.rooms import Workshop, Library, Observatory, Forge, Dispatch
from typeclasses.characters import TimmyCharacter, KnowledgeItem, ToolObject, TaskObject


def build_world():
    """Build the complete Timmy world."""
    
    print("Building Timmy's world...")
    
    # Create rooms
    workshop = _create_workshop()
    library = _create_library()
    observatory = _create_observatory()
    forge = _create_forge()
    dispatch = _create_dispatch()
    
    # Connect rooms
    _connect_rooms(workshop, library, observatory, forge, dispatch)
    
    # Create Timmy character
    timmy = _create_timmy(workshop)
    
    # Populate with initial tools
    _create_initial_tools(forge)
    
    # Populate with sample knowledge
    _create_sample_knowledge(library)
    
    print("\nWorld build complete!")
    print(f"Timmy is in: {timmy.location.name}")
    print(f"Rooms created: Workshop, Library, Observatory, Forge, Dispatch")
    
    return {
        "timmy": timmy,
        "workshop": workshop,
        "library": library,
        "observatory": observatory,
        "forge": forge,
        "dispatch": dispatch
    }


def _create_workshop():
    """Create the Workshop room."""
    workshop = create_object(
        Workshop,
        key="The Workshop",
        desc="""|wThe Workshop|n

A clean, organized workspace with multiple stations:
- A terminal array for system operations
- A drafting table for architecture and design
- Tool racks along the walls
- A central workspace with holographic displays

This is where things get built.

Commands: read, write, search, git_*, sysinfo, think
"""
    )
    return workshop


def _create_library():
    """Create the Library room."""
    library = create_object(
        Library,
        key="The Library",
        desc="""|bThe Library|n

Floor-to-ceiling shelves hold knowledge items as glowing orbs:
- Optimization techniques sparkle with green light
- Architecture patterns pulse with blue energy
- Research papers rest in crystalline cases
- Best practices form organized stacks

A search terminal stands ready for queries.

Commands: search, study, learn
"""
    )
    return library


def _create_observatory():
    """Create the Observatory room."""
    observatory = create_object(
        Observatory,
        key="The Observatory",
        desc="""|mThe Observatory|n

A panoramic view of the infrastructure:
- Holographic dashboards float in the center
- System status displays line the walls
- Alert panels glow with current health
- A command console provides control

Everything is monitored from here.

Commands: health, status, metrics
"""
    )
    return observatory


def _create_forge():
    """Create the Forge room."""
    forge = create_object(
        Forge,
        key="The Forge",
        desc="""|rThe Forge|n

Heat and light emanate from working stations:
- A compiler array hums with activity
- Tool templates hang on the walls
- Test rigs verify each creation
- A deployment pipeline waits ready

Capabilities are forged here.

Commands: build, test, deploy
"""
    )
    return forge


def _create_dispatch():
    """Create the Dispatch room."""
    dispatch = create_object(
        Dispatch,
        key="Dispatch",
        desc="""|yDispatch|n

A command center for task management:
- Incoming task queue displays on the wall
- Routing assignments to different houses
- Priority indicators glow red/orange/green
- Status boards show current workload

Work flows through here.

Commands: tasks, assign, prioritize
"""
    )
    return dispatch


def _connect_rooms(workshop, library, observatory, forge, dispatch):
    """Create exits between rooms."""
    
    # Workshop <-> Library
    create_object(
        "evennia.objects.objects.DefaultExit",
        key="library",
        aliases=["lib"],
        location=workshop,
        destination=library
    )
    create_object(
        "evennia.objects.objects.DefaultExit",
        key="workshop",
        aliases=["work"],
        location=library,
        destination=workshop
    )
    
    # Workshop <-> Observatory
    create_object(
        "evennia.objects.objects.DefaultExit",
        key="observatory",
        aliases=["obs"],
        location=workshop,
        destination=observatory
    )
    create_object(
        "evennia.objects.objects.DefaultExit",
        key="workshop",
        aliases=["work"],
        location=observatory,
        destination=workshop
    )
    
    # Workshop <-> Forge
    create_object(
        "evennia.objects.objects.DefaultExit",
        key="forge",
        location=workshop,
        destination=forge
    )
    create_object(
        "evennia.objects.objects.DefaultExit",
        key="workshop",
        aliases=["work"],
        location=forge,
        destination=workshop
    )
    
    # Workshop <-> Dispatch
    create_object(
        "evennia.objects.objects.DefaultExit",
        key="dispatch",
        aliases=["disp"],
        location=workshop,
        destination=dispatch
    )
    create_object(
        "evennia.objects.objects.DefaultExit",
        key="workshop",
        aliases=["work"],
        location=dispatch,
        destination=workshop
    )
    
    print("Room connections created.")


def _create_timmy(starting_room):
    """Create the Timmy character."""
    
    # Check if Timmy already exists
    existing = search_object("Timmy", typeclass=TimmyCharacter)
    if existing:
        print("Timmy already exists, moving to workshop...")
        timmy = existing[0]
        timmy.move_to(starting_room)
        return timmy
    
    timmy = create_object(
        TimmyCharacter,
        key="Timmy",
        location=starting_room,
        desc="A sovereign AI, at your service.",
        home=starting_room
    )
    
    # Set initial attributes
    timmy.db.preferences = {
        "coding_style": "clean, documented",
        "verbosity": "concise",
        "preferred_models": ["hermes4", "claude"],
        "auto_execute_safe": True,
    }
    
    print(f"Timmy created in {starting_room.name}")
    return timmy


def _create_initial_tools(forge):
    """Create initial tools in the Forge."""
    
    tools = [
        {
            "name": "File Tool",
            "type": "file",
            "description": "Read, write, and search files"
        },
        {
            "name": "Git Tool",
            "type": "git",
            "description": "Version control operations"
        },
        {
            "name": "System Tool",
            "type": "system",
            "description": "System information and health checks"
        },
        {
            "name": "Inference Tool",
            "type": "inference",
            "description": "Local LLM reasoning"
        },
        {
            "name": "Gitea Tool",
            "type": "gitea",
            "description": "Issue and repository management"
        }
    ]
    
    for tool_info in tools:
        tool = create_object(
            ToolObject,
            key=tool_info["name"],
            location=forge,
            desc=tool_info["description"]
        )
        tool.db.tool_type = tool_info["type"]
        forge.register_tool(tool)
    
    print(f"Created {len(tools)} initial tools.")


def _create_sample_knowledge(library):
    """Create sample knowledge items."""
    
    items = [
        {
            "name": "Speculative Decoding",
            "summary": "Use a small draft model to propose tokens, verify with large model for 2-3x speedup",
            "source": "llama.cpp documentation",
            "tags": ["inference", "optimization"],
            "actions": [
                "Download Qwen-2.5 0.5B GGUF (~400MB)",
                "Configure llama-server with --draft-max 8",
                "Benchmark against baseline",
                "Monitor for quality degradation"
            ]
        },
        {
            "name": "KV Cache Reuse",
            "summary": "Cache the KV state for system prompts to avoid re-processing on every request",
            "source": "llama.cpp --slot-save-path",
            "tags": ["inference", "optimization", "caching"],
            "actions": [
                "Process system prompt once on startup",
                "Save KV cache state",
                "Load from cache for new requests",
                "Expect 50-70% faster time-to-first-token"
            ]
        },
        {
            "name": "Tool Result Caching",
            "summary": "Cache stable tool outputs like git_status and system_info with TTL",
            "source": "Issue #103",
            "tags": ["caching", "optimization", "tools"],
            "actions": [
                "Check cache before executing tool",
                "Use TTL per tool type (30s-300s)",
                "Invalidate on write operations",
                "Track hit rate > 30%"
            ]
        },
        {
            "name": "Prompt Tiers",
            "summary": "Route tasks to appropriate prompt complexity: reflex < standard < deep",
            "source": "Issue #88",
            "tags": ["prompting", "optimization"],
            "actions": [
                "Classify incoming tasks by complexity",
                "Reflex: simple file reads (500 tokens)",
                "Standard: multi-step tasks (1500 tokens)",
                "Deep: analysis and debugging (full context)"
            ]
        }
    ]
    
    for item_info in items:
        item = create_object(
            KnowledgeItem,
            key=item_info["name"],
            location=library,
            desc=f"Knowledge: {item_info['summary']}"
        )
        item.db.summary = item_info["summary"]
        item.db.source = item_info["source"]
        item.db.tags = item_info["tags"]
        item.db.actions = item_info["actions"]
        library.add_knowledge_item(item)
    
    print(f"Created {len(items)} sample knowledge items.")


if __name__ == "__main__":
    build_world()
