#!/usr/bin/env python3
"""
Voice-to-Ralph Bridge
Watches a text file for voice input (from Wispr Flow or any dictation tool)
and converts it to Ralph Wiggum mission files.

Usage:
1. Open E:\genesis-system\VOICE_INPUT.txt in any editor
2. Dictate with Wispr Flow (or type)
3. Save the file
4. This script auto-generates mission file and can launch Ralph Loop

Voice Command Format:
"Project [NAME]. Objective [GOAL]. Success [CRITERIA]. Max [N] iterations. Go."
"""

import os
import re
import json
import time
import subprocess
from datetime import datetime
from pathlib import Path
from typing import Dict, Optional
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

# Paths
VOICE_INPUT_FILE = Path("/mnt/e/genesis-system/VOICE_INPUT.txt")
MISSION_OUTPUT = Path("/mnt/e/genesis-system/templates/current_mission.md")
MISSION_HISTORY = Path("/mnt/e/genesis-system/data/mission_history")
RALPH_TEMPLATE = Path("/mnt/e/genesis-system/templates/ralph_wiggum_template.md")


class VoiceCommandParser:
    """Parse natural language voice commands into structured mission data."""

    def parse(self, text: str) -> Dict:
        """Parse voice input into mission fields."""
        result = {
            "raw_text": text.strip(),
            "project_name": "unnamed_project",
            "objective": "",
            "success_criteria": [],
            "context_files": [],
            "max_iterations": 30,
            "auto_start": False,
            "parsed_at": datetime.now().isoformat()
        }

        text_clean = text.strip()

        # Check for "go" or "start" at end - means auto-launch
        if text_clean.lower().endswith((" go", " go.", " start", " start.", " execute", " execute.")):
            result["auto_start"] = True

        # Extract project name
        # Patterns: "project: X", "project X", "new project X"
        patterns = [
            r"(?:new\s+)?project[:\s]+([a-zA-Z0-9_-]+)",
            r"(?:build|create|make)\s+(?:a\s+)?([a-zA-Z0-9_-]+)",
        ]
        for pattern in patterns:
            match = re.search(pattern, text, re.IGNORECASE)
            if match:
                result["project_name"] = match.group(1).lower().replace(" ", "_")
                break

        # Extract objective
        obj_patterns = [
            r"objective[:\s]+(.+?)(?:\.|success|criteria|read|max|go|$)",
            r"goal[:\s]+(.+?)(?:\.|success|criteria|read|max|go|$)",
            r"(?:i\s+want\s+to|we\s+need\s+to|please)\s+(.+?)(?:\.|success|criteria|max|go|$)",
        ]
        for pattern in obj_patterns:
            match = re.search(pattern, text, re.IGNORECASE)
            if match:
                result["objective"] = match.group(1).strip()
                break

        # If no objective found, use most of the text
        if not result["objective"] and len(text_clean) > 20:
            # Remove project name mention and use rest as objective
            obj_text = re.sub(r"(?:new\s+)?project[:\s]+[a-zA-Z0-9_-]+\.?\s*", "", text_clean, flags=re.IGNORECASE)
            obj_text = re.sub(r"\s*(go|start|execute)\.?\s*$", "", obj_text, flags=re.IGNORECASE)
            result["objective"] = obj_text.strip()

        # Extract success criteria
        success_patterns = [
            r"success(?:\s+means)?[:\s]+(.+?)(?:\.|read|max|go|$)",
            r"criteria[:\s]+(.+?)(?:\.|read|max|go|$)",
            r"done\s+when[:\s]+(.+?)(?:\.|read|max|go|$)",
        ]
        for pattern in success_patterns:
            match = re.search(pattern, text, re.IGNORECASE)
            if match:
                criteria_text = match.group(1).strip()
                # Split by "and" or commas
                criteria_list = re.split(r",\s*|\s+and\s+", criteria_text)
                result["success_criteria"] = [c.strip() for c in criteria_list if c.strip()]
                break

        # Extract max iterations
        iter_match = re.search(r"max\s+(\d+)\s*(?:iterations?)?", text, re.IGNORECASE)
        if iter_match:
            result["max_iterations"] = int(iter_match.group(1))

        # Extract file references
        file_patterns = [
            r"(?:read|check|look at|files?)[:\s]+(.+?)(?:\.|max|go|$)",
            r"context[:\s]+(.+?)(?:\.|max|go|$)",
        ]
        for pattern in file_patterns:
            match = re.search(pattern, text, re.IGNORECASE)
            if match:
                files_text = match.group(1).strip()
                result["context_files"] = [f.strip() for f in re.split(r",\s*|\s+and\s+", files_text)]
                break

        return result


class MissionGenerator:
    """Generate Ralph Wiggum mission files from parsed voice commands."""

    def generate(self, parsed: Dict) -> str:
        """Generate markdown mission file content."""
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

        content = f"""# MISSION: {parsed['project_name'].upper()}
## Auto-generated from voice command

**Generated**: {timestamp}
**Auto-start**: {"YES" if parsed.get('auto_start') else "NO"}

---

## 🎯 MISSION BRIEF

### Project Name
`{parsed['project_name']}`

### Objective
{parsed.get('objective', 'Complete the requested task')}

### Success Criteria
"""
        if parsed.get('success_criteria'):
            for criterion in parsed['success_criteria']:
                content += f"- [ ] {criterion}\n"
        else:
            content += "- [ ] Task completed successfully\n- [ ] All tests pass\n"

        content += f"""
### Context Files
"""
        if parsed.get('context_files'):
            for f in parsed['context_files']:
                content += f"- `{f}`\n"
        else:
            content += "- Read relevant files as needed\n"

        content += f"""
### Configuration
- **Max iterations**: {parsed.get('max_iterations', 30)}
- **Timeout**: 4 hours
- **Model**: Opus 4.5

---

## 🔄 RALPH LOOP COMMAND

```bash
/ralph-loop "{parsed.get('objective', parsed['project_name'])}" --max-iterations {parsed.get('max_iterations', 30)}
```

---

## 📝 RAW VOICE INPUT

```
{parsed.get('raw_text', '')}
```

---

*Ready for execution. Say "go" or run the ralph-loop command above.*
"""
        return content

    def save(self, content: str, parsed: Dict) -> Path:
        """Save mission file and archive to history."""
        # Save current mission
        MISSION_OUTPUT.parent.mkdir(parents=True, exist_ok=True)
        with open(MISSION_OUTPUT, 'w') as f:
            f.write(content)

        # Archive to history
        MISSION_HISTORY.mkdir(parents=True, exist_ok=True)
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        history_file = MISSION_HISTORY / f"{timestamp}_{parsed['project_name']}.md"
        with open(history_file, 'w') as f:
            f.write(content)

        return MISSION_OUTPUT


class VoiceInputHandler(FileSystemEventHandler):
    """Watch for changes to the voice input file."""

    def __init__(self):
        self.parser = VoiceCommandParser()
        self.generator = MissionGenerator()
        self.last_content = ""
        self.last_processed = 0

    def on_modified(self, event):
        if not event.src_path.endswith("VOICE_INPUT.txt"):
            return

        # Debounce - wait for file to settle
        current_time = time.time()
        if current_time - self.last_processed < 1:
            return

        try:
            time.sleep(0.5)  # Wait for file write to complete
            with open(VOICE_INPUT_FILE, 'r') as f:
                content = f.read().strip()

            if not content or content == self.last_content:
                return

            self.last_content = content
            self.last_processed = current_time

            print(f"\n{'='*60}")
            print(f"📝 Voice input detected!")
            print(f"{'='*60}")
            print(f"Input: {content[:100]}...")

            # Parse
            parsed = self.parser.parse(content)
            print(f"\n✅ Parsed:")
            print(f"   Project: {parsed['project_name']}")
            print(f"   Objective: {parsed['objective'][:50]}...")
            print(f"   Max iterations: {parsed['max_iterations']}")
            print(f"   Auto-start: {parsed['auto_start']}")

            # Generate mission file
            mission_content = self.generator.generate(parsed)
            mission_path = self.generator.save(mission_content, parsed)

            print(f"\n📄 Mission file saved: {mission_path}")

            if parsed['auto_start']:
                print(f"\n🚀 AUTO-START enabled!")
                print(f"   Ready to launch Ralph Loop...")
                # Could trigger ralph loop here
            else:
                print(f"\n⏸️  Waiting for 'go' command or manual launch")
                print(f"   Run: /ralph-loop \"{parsed['objective']}\"")

            print(f"\n{'='*60}\n")

        except Exception as e:
            print(f"Error processing voice input: {e}")


def create_input_file():
    """Create the voice input file if it doesn't exist."""
    if not VOICE_INPUT_FILE.exists():
        VOICE_INPUT_FILE.parent.mkdir(parents=True, exist_ok=True)
        with open(VOICE_INPUT_FILE, 'w') as f:
            f.write("""# GENESIS VOICE INPUT
#
# Dictate your project here using Wispr Flow or any voice tool.
# Save the file and Genesis will auto-generate a mission.
#
# Format:
# "Project [NAME]. Objective [GOAL]. Success [CRITERIA]. Max [N] iterations. Go."
#
# Example:
# "Project voice-dashboard. Objective build real-time agent monitor.
#  Success means websocket updates every second. Max 50 iterations. Go."
#
# Clear this file and dictate below:
# ─────────────────────────────────────────

""")
        print(f"Created: {VOICE_INPUT_FILE}")


def main():
    """Main entry point."""
    print("""
╔═══════════════════════════════════════════════════════════╗
║         GENESIS VOICE-TO-RALPH BRIDGE                     ║
║                                                           ║
║  Watching: E:\\genesis-system\\VOICE_INPUT.txt             ║
║  Output:   E:\\genesis-system\\templates\\current_mission.md ║
║                                                           ║
║  1. Open VOICE_INPUT.txt in any editor                    ║
║  2. Dictate with Wispr Flow (or type)                     ║
║  3. Save the file                                         ║
║  4. Mission auto-generates!                               ║
║                                                           ║
║  Press Ctrl+C to stop                                     ║
╚═══════════════════════════════════════════════════════════╝
""")

    create_input_file()

    # Set up file watcher
    event_handler = VoiceInputHandler()
    observer = Observer()
    observer.schedule(event_handler, str(VOICE_INPUT_FILE.parent), recursive=False)
    observer.start()

    print(f"👂 Listening for voice input...\n")

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
        print("\n\n👋 Voice-to-Ralph bridge stopped.")

    observer.join()


if __name__ == "__main__":
    main()
