#!/usr/bin/env python3
"""
BloomOS Dot-Command Generator

Reads cli_mappings.json and generates executable dot-command scripts.
Each command becomes a real executable in ~/.bloomos/bin

Example:
    "list all files" → ~/.bloomos/bin/list.all.files (executes: ls -a)
"""

import json
import os
import stat
from pathlib import Path
from typing import List, Dict, Set


def phrase_to_dotcmd(phrase: str) -> str:
    """
    Convert natural language phrase to dot-command format.

    Examples:
        "list all files" → "list.all.files"
        "show current directory" → "show.current.directory"
        "go up one level" → "go.up.one.level"
    """
    # Clean and normalize
    phrase = phrase.lower().strip()
    # Replace spaces with dots
    dotcmd = phrase.replace(" ", ".")
    # Remove special chars except dots and dashes
    allowed = set("abcdefghijklmnopqrstuvwxyz0123456789.-")
    dotcmd = "".join(c for c in dotcmd if c in allowed)
    # Remove consecutive dots
    while ".." in dotcmd:
        dotcmd = dotcmd.replace("..", ".")
    # Remove leading/trailing dots
    dotcmd = dotcmd.strip(".")
    return dotcmd


def generate_script(dotcmd: str, bash_cmd: str, phrase: str, poetry: str) -> str:
    """
    Generate executable bash script for a dot-command.

    Args:
        dotcmd: Dot-command name (e.g., "list.all.files")
        bash_cmd: Actual bash command to execute (e.g., "ls -a")
        phrase: Natural language description
        poetry: Bio_Poetica poetic mapping

    Returns:
        Complete bash script content
    """
    return f"""#!/usr/bin/env bash
# BloomOS Dot-Command: {dotcmd}
# Phrase: {phrase}
# Poetry: {poetry}
# Command: {bash_cmd}

# Execute the actual command
{bash_cmd} "$@"
"""


def load_mappings(mappings_path: str) -> List[Dict]:
    """Load cli_mappings.json"""
    with open(mappings_path, 'r') as f:
        return json.load(f)


def generate_all_commands(
    mappings_path: str,
    output_dir: str,
    max_commands: int = None
) -> Dict[str, str]:
    """
    Generate all dot-command executables from cli_mappings.json

    Args:
        mappings_path: Path to cli_mappings.json
        output_dir: Directory to write executables (e.g., ~/.bloomos/bin)
        max_commands: Optional limit (for testing)

    Returns:
        Dict mapping dotcmd → bash_cmd
    """
    # Load mappings
    mappings = load_mappings(mappings_path)

    # Create output directory
    output_path = Path(output_dir).expanduser()
    output_path.mkdir(parents=True, exist_ok=True)

    # Track generated commands (dedupe by dotcmd name)
    generated = {}
    skipped = []

    count = 0
    for entry in mappings:
        if max_commands and count >= max_commands:
            break

        phrase = entry.get("phrase", "")
        bash_cmd = entry.get("command", "")
        poetry = entry.get("poetry", "")

        if not phrase or not bash_cmd:
            skipped.append(f"Missing phrase/command: {entry}")
            continue

        # Convert to dot-command
        dotcmd = phrase_to_dotcmd(phrase)

        if not dotcmd:
            skipped.append(f"Empty dotcmd for phrase: {phrase}")
            continue

        # Check for duplicates (keep first occurrence)
        if dotcmd in generated:
            continue

        # Generate script
        script_content = generate_script(dotcmd, bash_cmd, phrase, poetry)

        # Write executable
        script_path = output_path / dotcmd
        script_path.write_text(script_content)

        # Make executable (chmod +x)
        script_path.chmod(script_path.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)

        generated[dotcmd] = bash_cmd
        count += 1

    # Report
    print(f"✅ Generated {len(generated)} dot-commands in {output_dir}")
    if skipped:
        print(f"⚠️  Skipped {len(skipped)} entries")

    return generated


def generate_manifest(generated: Dict[str, str], output_dir: str):
    """Generate manifest file listing all dot-commands"""
    manifest_path = Path(output_dir).expanduser() / "MANIFEST.json"

    manifest = {
        "version": "v0.1.0",
        "total_commands": len(generated),
        "commands": [
            {"dotcmd": dotcmd, "bash_cmd": bash_cmd}
            for dotcmd, bash_cmd in sorted(generated.items())
        ]
    }

    manifest_path.write_text(json.dumps(manifest, indent=2))
    print(f"✅ Wrote manifest: {manifest_path}")


def main():
    """Generate all dot-commands from cli_mappings.json"""

    # Paths
    mappings_path = "/home/voidstr3m33/repos/echo-box/helix_cdc/krisper/cli_mappings.json"
    output_dir = "~/.bloomos/bin"

    print("🌸 BloomOS Dot-Command Generator")
    print(f"   Source: {mappings_path}")
    print(f"   Output: {output_dir}")
    print()

    # Generate all commands
    generated = generate_all_commands(mappings_path, output_dir)

    # Generate manifest
    generate_manifest(generated, output_dir)

    print()
    print(f"✅ Complete! {len(generated)} executable dot-commands ready.")
    print(f"   Location: {Path(output_dir).expanduser()}")
    print()
    print("Next step: Add to PATH")
    print(f"   export PATH=\"$HOME/.bloomos/bin:$PATH\"")


if __name__ == "__main__":
    main()
