#!/usr/bin/env python3
"""
Pipo Mirror — CLI clone of Pipo assistant for SSH access
Loads Chicho's memory + skills, provides interactive REPL with pi-zen backend.
"""

import os
import sys
import json
import subprocess
from pathlib import Path

# ─── Configuration ───────────────────────────────────────────────────────────
HOME = Path.home()
HERMES_DIR = HOME / ".hermes"
MEMORIES_DIR = HERMES_DIR / "memories"
SKILLS_DIR = HERMES_DIR / "skills"
SESSION_DIR = HOME / ".pipo-mirror" / "sessions"
SESSION_FILE = SESSION_DIR / "session.jsonl"

# Skill selection: 3 simple, useful, local-friendly skills
SELECTED_SKILLS = [
    "github/github-issues",      # GitHub issue management via gh CLI
    "productivity/nano-pdf",     # PDF text editing via natural language
    "software-development/android-dev",  # ADB/Android build info
]

# ─── Memory Loading ───────────────────────────────────────────────────────────
def load_memory():
    """Load MEMORY.md and USER.md from Hermes memories directory."""
    memory = {}
    
    memory_path = MEMORIES_DIR / "MEMORY.md"
    if memory_path.exists():
        memory["context"] = memory_path.read_text()
    else:
        memory["context"] = "# Memory not found at " + str(memory_path)
    
    user_path = MEMORIES_DIR / "USER.md"
    if user_path.exists():
        memory["user"] = user_path.read_text()
    else:
        memory["user"] = "# User profile not found"
    
    return memory

def load_soul():
    """Load SOUL.md — Pipo's persona."""
    soul_path = HERMES_DIR / "SOUL.md"
    if soul_path.exists():
        return soul_path.read_text()
    return "You are a helpful AI assistant."

def load_skills():
    """Load selected skills' SKILL.md files."""
    loaded = {}
    for skill_rel in SELECTED_SKILLS:
        skill_path = SKILLS_DIR / skill_rel / "SKILL.md"
        if skill_path.exists():
            loaded[skill_rel] = skill_path.read_text()
        else:
            loaded[skill_rel] = f"# Skill not found: {skill_rel}"
    return loaded

# ─── Session Persistence ──────────────────────────────────────────────────────
def ensure_session_dir():
    SESSION_DIR.mkdir(parents=True, exist_ok=True)

def load_session():
    """Load conversation history from session file."""
    messages = []
    if SESSION_FILE.exists():
        with open(SESSION_FILE, "r") as f:
            for line in f:
                line = line.strip()
                if line:
                    try:
                        messages.append(json.loads(line))
                    except json.JSONDecodeError:
                        pass
    return messages

def save_message(role, content):
    """Append a message to the session file."""
    ensure_session_dir()
    with open(SESSION_FILE, "a") as f:
        f.write(json.dumps({"role": role, "content": content}, ensure_ascii=False) + "\n")

# ─── Build System Prompt ──────────────────────────────────────────────────────
def build_system_prompt(memory, soul, skills):
    """Construct the system prompt for pi-zen."""
    skill_section = "\n\n".join([
        f"## SKILL: {name}\n{content}"
        for name, content in skills.items()
    ])
    
    return f"""# You are Pipo — Chicho's AI assistant (CLI mode)

You are running in a local CLI (SSH), NOT Discord. Keep responses concise.

## Soul (Your Persona)
{soul}

## User Context
{memory['context']}

## User Profile
{memory['user']}

## Available Skills
{skill_section}

## Guidelines
- Be direct and concise — Chicho hates filler
- Use available skills when relevant
- Execute bash commands via tool when helpful
- If you need to do something that requires user confirmation, give clear final instructions
- Never say "Great question!" or similar fluff

"""

# ─── Call pi-zen ──────────────────────────────────────────────────────────────
def call_zen(system_prompt, conversation_history, user_message):
    """Call pi-zen as subprocess with full context."""
    
    # Build conversation for context window
    # We pass the last N exchanges to give context
    context_msgs = conversation_history[-10:] if conversation_history else []
    
    # Build full prompt for pi-zen non-interactive mode
    cmd = [
        "pi-zen",
        "--provider", "opencode",
        "--no-tools",  # We want text output, not tool invocations
        "--system-prompt", system_prompt,
    ]
    
    # For pi-zen -p mode, we need to build the conversation as a prompt
    prompt_parts = []
    
    # Add recent history for context
    for msg in context_msgs:
        if msg["role"] == "user":
            prompt_parts.append(f"[User]: {msg['content']}")
        elif msg["role"] == "assistant":
            prompt_parts.append(f"[Pipo]: {msg['content']}")
    
    prompt_parts.append(f"[User]: {user_message}")
    
    full_prompt = "\n".join(prompt_parts)
    
    try:
        result = subprocess.run(
            cmd,
            input=full_prompt,
            capture_output=True,
            text=True,
            timeout=120,
        )
        
        if result.returncode == 0:
            return result.stdout.strip()
        else:
            return f"❌ Error: {result.stderr or 'pi-zen failed with code ' + str(result.returncode)}"
    except subprocess.TimeoutExpired:
        return "❌ Timeout: pi-zen took too long (>120s)"
    except Exception as e:
        return f"❌ Exception: {str(e)}"

# ─── REPL ─────────────────────────────────────────────────────────────────────
def main():
    print("🤖 Pipo Mirror — CLI mode (SSH)")
    print("=" * 50)
    
    # Load all context
    print("📚 Loading memory and skills...")
    memory = load_memory()
    soul = load_soul()
    skills = load_skills()
    
    print(f"   ✓ Memory: {len(memory['context'])} chars")
    print(f"   ✓ User: {len(memory['user'])} chars")
    print(f"   ✓ Soul: loaded")
    print(f"   ✓ Skills: {', '.join(skills.keys())}")
    print()
    
    # Build system prompt once
    system_prompt = build_system_prompt(memory, soul, skills)
    
    # Load conversation history
    conversation = load_session()
    print(f"📝 Loaded {len(conversation)} previous messages")
    print()
    print("Type your message and press Enter. Ctrl+C or 'exit' to quit.")
    print("-" * 50)
    
    try:
        while True:
            try:
                user_input = input("\n[You] ").strip()
            except EOFError:
                break
            
            if not user_input:
                continue
            
            if user_input.lower() in ("exit", "quit", "q"):
                print("👋 Goodbye!")
                break
            
            # Save user message
            save_message("user", user_input)
            conversation.append({"role": "user", "content": user_input})
            
            # Call pi-zen
            print("\n[Pipo] ", end="", flush=True)
            response = call_zen(system_prompt, conversation, user_input)
            
            # Print response (handle multiline)
            print(response)
            
            # Save assistant response
            save_message("assistant", response)
            conversation.append({"role": "assistant", "content": response})
            
    except KeyboardInterrupt:
        print("\n👋 Goodbye!")
    
    print("\n💾 Session saved.")

if __name__ == "__main__":
    main()