#!/usr/bin/env python3
"""
RTLViz Dependency Manager - Cross-platform dependency checking and installation.
"""

import os
import sys
import shutil
import subprocess
import platform
from pathlib import Path
from typing import Tuple, List, Optional


def get_platform_info() -> dict:
    """Get current platform information."""
    return {
        "system": platform.system(),  # 'Windows', 'Darwin', 'Linux'
        "machine": platform.machine(),  # 'x86_64', 'arm64', 'AMD64'
        "python": platform.python_version(),
        "is_mac": platform.system() == "Darwin",
        "is_windows": platform.system() == "Windows",
        "is_linux": platform.system() == "Linux",
        "is_arm": platform.machine() in ("arm64", "aarch64"),
    }


def check_graphviz_binary() -> Tuple[bool, str]:
    """Check if Graphviz 'dot' binary is installed."""
    dot_path = shutil.which("dot")
    if dot_path:
        try:
            result = subprocess.run(
                ["dot", "-V"], capture_output=True, text=True, timeout=5
            )
            version = result.stderr.strip() if result.stderr else "unknown"
            return True, f"Found: {dot_path} ({version})"
        except Exception:
            return True, f"Found: {dot_path}"
    return False, "Not found"


def check_python_graphviz() -> Tuple[bool, str]:
    """Check if graphviz Python package is installed."""
    try:
        import graphviz
        return True, f"Version {graphviz.__version__}"
    except ImportError:
        return False, "Not installed"


def check_mcp() -> Tuple[bool, str]:
    """Check if MCP package is installed."""
    try:
        import mcp
        version = getattr(mcp, "__version__", "unknown")
        return True, f"Version {version}"
    except ImportError:
        return False, "Not installed"


def get_graphviz_install_instructions() -> str:
    """Get platform-specific Graphviz installation instructions."""
    info = get_platform_info()
    
    if info["is_mac"]:
        return """
## Install Graphviz on macOS

Option 1 - Homebrew (recommended):
    brew install graphviz

Option 2 - MacPorts:
    sudo port install graphviz

Option 3 - Direct download:
    https://graphviz.org/download/
    
Note for Apple Silicon (M1/M2/M3):
    Homebrew installs native ARM version automatically.
"""
    elif info["is_windows"]:
        return """
## Install Graphviz on Windows

Option 1 - Chocolatey (recommended):
    choco install graphviz

Option 2 - Winget:
    winget install graphviz

Option 3 - Direct download:
    https://graphviz.org/download/
    Download the .exe installer and run it.
    
IMPORTANT: After installation, add to PATH:
    1. Open System Properties > Environment Variables
    2. Add C:\\Program Files\\Graphviz\\bin to PATH
    3. Restart your terminal/IDE
"""
    else:  # Linux
        return """
## Install Graphviz on Linux

Debian/Ubuntu:
    sudo apt update && sudo apt install graphviz

Fedora/RHEL:
    sudo dnf install graphviz

Arch Linux:
    sudo pacman -S graphviz

Alpine:
    apk add graphviz
"""


def check_all_dependencies() -> dict:
    """Check all dependencies and return status."""
    results = {
        "platform": get_platform_info(),
        "graphviz_binary": check_graphviz_binary(),
        "graphviz_python": check_python_graphviz(),
        "mcp": check_mcp(),
        "all_ok": True,
        "critical_missing": [],
        "optional_missing": [],
    }
    
    # MCP is critical
    if not results["mcp"][0]:
        results["all_ok"] = False
        results["critical_missing"].append("mcp")
    
    # Python graphviz is critical
    if not results["graphviz_python"][0]:
        results["all_ok"] = False
        results["critical_missing"].append("graphviz (Python package)")
    
    # Graphviz binary is optional (SVG export only)
    if not results["graphviz_binary"][0]:
        results["optional_missing"].append("graphviz (system binary)")
    
    return results


def print_dependency_status() -> bool:
    """Print dependency status and return True if all critical deps are met."""
    results = check_all_dependencies()
    info = results["platform"]
    
    print("=" * 60)
    print("RTLViz Dependency Check")
    print("=" * 60)
    print(f"Platform: {info['system']} ({info['machine']})")
    print(f"Python: {info['python']}")
    print()
    
    # Critical dependencies
    print("Critical Dependencies:")
    print(f"  [{'OK' if results['mcp'][0] else 'MISSING'}] MCP Package: {results['mcp'][1]}")
    print(f"  [{'OK' if results['graphviz_python'][0] else 'MISSING'}] graphviz Python: {results['graphviz_python'][1]}")
    
    # Optional dependencies
    print()
    print("Optional Dependencies (for SVG export):")
    print(f"  [{'OK' if results['graphviz_binary'][0] else 'MISSING'}] Graphviz Binary: {results['graphviz_binary'][1]}")
    
    print()
    
    if results["critical_missing"]:
        print("CRITICAL: Missing dependencies:")
        for dep in results["critical_missing"]:
            print(f"  - {dep}")
        print()
        print("Install with: pip install rtlviz")
        return False
    
    if results["optional_missing"]:
        print("OPTIONAL: Missing for full functionality:")
        for dep in results["optional_missing"]:
            print(f"  - {dep}")
        print()
        print(get_graphviz_install_instructions())
        print()
        print("Note: RTLViz works without Graphviz binary!")
        print("      HTML diagrams render in-browser using Viz.js (WASM)")
        print("      Graphviz binary is only needed for standalone SVG export")
    else:
        print("All dependencies are installed!")
    
    print("=" * 60)
    return True


def ensure_dependencies() -> bool:
    """Ensure all critical dependencies are installed. Returns True if OK."""
    results = check_all_dependencies()
    return results["all_ok"]


# CLI entry point
def main():
    """CLI entry point for dependency checking."""
    success = print_dependency_status()
    sys.exit(0 if success else 1)


if __name__ == "__main__":
    main()

