#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
groverifier: GROMACS GPU Compatibility Checker

Author: Vishal Ravi
Email: dev.vishalravi@gmail.com
License: MIT
"""

import subprocess
import shutil
import platform
import sys
import argparse
import json
import re
import os
from datetime import datetime

# ANSI Color codes for professional terminal output
class Colors:
    # Standard colors
    RED = '\033[91m'
    GREEN = '\033[92m'
    YELLOW = '\033[93m'
    BLUE = '\033[94m'
    MAGENTA = '\033[95m'
    CYAN = '\033[96m'
    WHITE = '\033[97m'
    GRAY = '\033[90m'
    
    # Bright colors
    BRIGHT_RED = '\033[1;91m'
    BRIGHT_GREEN = '\033[1;92m'
    BRIGHT_YELLOW = '\033[1;93m'
    BRIGHT_BLUE = '\033[1;94m'
    BRIGHT_MAGENTA = '\033[1;95m'
    BRIGHT_CYAN = '\033[1;96m'
    BRIGHT_WHITE = '\033[1;97m'
    
    # Styles
    BOLD = '\033[1m'
    DIM = '\033[2m'
    ITALIC = '\033[3m'
    UNDERLINE = '\033[4m'
    RESET = '\033[0m'
    
    # Background colors
    BG_BLACK = '\033[40m'
    BG_BLUE = '\033[44m'
    BG_GREEN = '\033[42m'
    BG_RED = '\033[41m'

def format_status(status, message=""):
    """Format status indicators with colors and symbols"""
    if status:
        return f"{Colors.BRIGHT_GREEN}✓{Colors.RESET} {Colors.GREEN}{message}{Colors.RESET}" if message else f"{Colors.BRIGHT_GREEN}✓{Colors.RESET}"
    else:
        return f"{Colors.BRIGHT_RED}✗{Colors.RESET} {Colors.RED}{message}{Colors.RESET}" if message else f"{Colors.BRIGHT_RED}✗{Colors.RESET}"

def format_header(title, width=80):
    """Format section headers with professional styling"""
    padding = (width - len(title) - 2) // 2
    border = "═" * width
    header = f"{Colors.BRIGHT_CYAN}{border}{Colors.RESET}\n"
    header += f"{Colors.BRIGHT_CYAN}║{Colors.RESET}{' ' * padding}{Colors.BOLD}{Colors.BRIGHT_WHITE}{title}{Colors.RESET}{' ' * (width - len(title) - padding - 2)}{Colors.BRIGHT_CYAN}║{Colors.RESET}\n"
    header += f"{Colors.BRIGHT_CYAN}{border}{Colors.RESET}"
    return header

def format_section(title, icon="", width=80):
    """Format section titles with icons and styling"""
    section_line = f"{Colors.BRIGHT_BLUE}┌─{Colors.RESET} {icon} {Colors.BOLD}{Colors.BRIGHT_WHITE}{title}{Colors.RESET}"
    remaining = width - len(title) - len(icon) - 5
    if remaining > 0:
        section_line += f" {Colors.BRIGHT_BLUE}{'─' * remaining}┐{Colors.RESET}"
    return section_line

def format_value(label, value, unit="", status=None, indent=0):
    """Format key-value pairs with professional styling"""
    prefix = "  " * indent
    if status is not None:
        status_icon = format_status(status)
        return f"{prefix}{Colors.BRIGHT_BLUE}│{Colors.RESET} {status_icon} {Colors.WHITE}{label}:{Colors.RESET} {Colors.BRIGHT_WHITE}{value}{Colors.RESET}{Colors.DIM}{unit}{Colors.RESET}"
    else:
        return f"{prefix}{Colors.BRIGHT_BLUE}│{Colors.RESET} {Colors.CYAN}{label}:{Colors.RESET} {Colors.BRIGHT_WHITE}{value}{Colors.RESET}{Colors.DIM}{unit}{Colors.RESET}"

def format_progress_bar(percentage, width=30, show_percentage=True):
    """Create a professional progress bar"""
    filled = int(width * percentage / 100)
    bar = "█" * filled + "░" * (width - filled)
    
    # Color based on percentage
    if percentage < 30:
        color = Colors.BRIGHT_GREEN
    elif percentage < 70:
        color = Colors.BRIGHT_YELLOW
    else:
        color = Colors.BRIGHT_RED
    
    percentage_text = f" {percentage:5.1f}%" if show_percentage else ""
    return f"{color}[{bar}]{Colors.RESET}{percentage_text}"

def run_cmd(cmd):
    try:
        result = subprocess.run(cmd, capture_output=True, text=True)
        return result.stdout.strip(), result.stderr.strip()
    except Exception as e:
        return "", str(e)

def check_gromacs_installed():
    gmx_path = shutil.which("gmx")
    return (True, gmx_path) if gmx_path else (False, None)

def get_gromacs_version():
    stdout, _ = run_cmd(["gmx", "--version"])
    for line in stdout.splitlines():
        if "GROMACS version" in line:
            return line.split()[-1]
    return "Unknown"

def get_detailed_gromacs_info():
    """Get detailed GROMACS installation information"""
    stdout, stderr = run_cmd(["gmx", "--version"])
    info = {
        "version": "Unknown",
        "build_info": {},
        "libraries": [],
        "precision": "Unknown",
        "simd": "Unknown",
        "fft": "Unknown",
        "mpi_support": False,
        "gpu_support": False,
        "build_date": "Unknown"
    }
    
    if not stdout:
        return info
    
    lines = stdout.splitlines()
    for i, line in enumerate(lines):
        line = line.strip()
        
        # Version
        if "GROMACS version" in line:
            info["version"] = line.split()[-1]
        
        # Build date
        if "released on" in line:
            try:
                date_match = re.search(r'released on (.+)', line)
                if date_match:
                    info["build_date"] = date_match.group(1)
            except:
                pass
        
        # Precision
        if "precision" in line.lower():
            if "double" in line.lower():
                info["precision"] = "Double"
            elif "single" in line.lower():
                info["precision"] = "Single"
        
        # SIMD
        if "simd" in line.lower():
            simd_match = re.search(r'SIMD\s+(\w+)', line)
            if simd_match:
                info["simd"] = simd_match.group(1)
        
        # FFT
        if "fft" in line.lower():
            fft_match = re.search(r'FFT\s+(\w+)', line)
            if fft_match:
                info["fft"] = fft_match.group(1)
        
        # GPU support
        if "gpu" in line.lower() or "cuda" in line.lower() or "opencl" in line.lower():
            info["gpu_support"] = True
        
        # MPI support
        if "mpi" in line.lower() and "enabled" in line.lower():
            info["mpi_support"] = True
    
    return info

def check_gromacs_gpu_support():
    stdout, stderr = run_cmd(["gmx", "mdrun", "-h"])
    combined = stdout + stderr
    return "GPU" in combined or "cuda" in combined.lower() or "OpenCL" in combined

def check_nvidia_gpu():
    stdout, stderr = run_cmd(["nvidia-smi"])
    return ("NVIDIA-SMI" in stdout, stdout.strip() if stdout else stderr.strip())

def get_detailed_gpu_info():
    """Get detailed GPU information including memory usage"""
    gpu_info = {
        "nvidia_driver_version": "Not Available",
        "cuda_version": "Not Available",
        "gpus": [],
        "total_gpus": 0
    }
    
    # Check nvidia-smi
    stdout, stderr = run_cmd(["nvidia-smi", "--query-gpu=index,name,memory.total,memory.used,memory.free,utilization.gpu,utilization.memory,temperature.gpu,power.draw,power.limit", "--format=csv,noheader,nounits"])
    
    if stdout:
        # Get driver and CUDA version from nvidia-smi
        driver_stdout, _ = run_cmd(["nvidia-smi"])
        if driver_stdout:
            lines = driver_stdout.splitlines()
            for line in lines:
                if "Driver Version:" in line:
                    try:
                        parts = line.split()
                        driver_idx = parts.index("Version:") + 1
                        gpu_info["nvidia_driver_version"] = parts[driver_idx]
                        if "CUDA" in line:
                            cuda_idx = parts.index("Version:") + 3
                            if cuda_idx < len(parts):
                                gpu_info["cuda_version"] = parts[cuda_idx]
                    except:
                        pass
        
        # Parse GPU details
        for line in stdout.strip().splitlines():
            if line.strip():
                parts = [p.strip() for p in line.split(',')]
                if len(parts) >= 6:
                    try:
                        gpu = {
                            "index": int(parts[0]),
                            "name": parts[1],
                            "memory_total_mb": int(parts[2]) if parts[2] != 'N/A' else 0,
                            "memory_used_mb": int(parts[3]) if parts[3] != 'N/A' else 0,
                            "memory_free_mb": int(parts[4]) if parts[4] != 'N/A' else 0,
                            "gpu_utilization_percent": int(parts[5]) if parts[5] != 'N/A' else 0,
                            "memory_utilization_percent": int(parts[6]) if len(parts) > 6 and parts[6] != 'N/A' else 0,
                            "temperature_c": int(parts[7]) if len(parts) > 7 and parts[7] != 'N/A' else 0,
                            "power_draw_w": float(parts[8]) if len(parts) > 8 and parts[8] != 'N/A' else 0,
                            "power_limit_w": float(parts[9]) if len(parts) > 9 and parts[9] != 'N/A' else 0
                        }
                        gpu_info["gpus"].append(gpu)
                    except (ValueError, IndexError):
                        continue
        
        gpu_info["total_gpus"] = len(gpu_info["gpus"])
    
    return gpu_info

def get_memory_usage():
    """Get detailed memory usage information"""
    try:
        import psutil
        mem = psutil.virtual_memory()
        swap = psutil.swap_memory()
        
        return {
            "total_gb": round(mem.total / (1024**3), 2),
            "available_gb": round(mem.available / (1024**3), 2),
            "used_gb": round(mem.used / (1024**3), 2),
            "free_gb": round(mem.free / (1024**3), 2),
            "usage_percent": mem.percent,
            "swap_total_gb": round(swap.total / (1024**3), 2),
            "swap_used_gb": round(swap.used / (1024**3), 2),
            "swap_free_gb": round(swap.free / (1024**3), 2),
            "swap_usage_percent": swap.percent
        }
    except ImportError:
        return {"error": "psutil not available"}

def get_cpu_usage():
    """Get CPU usage information"""
    try:
        import psutil
        return {
            "usage_percent": psutil.cpu_percent(interval=1),
            "per_cpu_percent": psutil.cpu_percent(interval=1, percpu=True),
            "load_average": os.getloadavg() if hasattr(os, 'getloadavg') else None,
            "logical_cores": psutil.cpu_count(logical=True),
            "physical_cores": psutil.cpu_count(logical=False)
        }
    except ImportError:
        return {"error": "psutil not available"}

def get_system_info():
    try:
        import psutil
        boot_time = datetime.fromtimestamp(psutil.boot_time())
        
        return {
            "os": f"{platform.system()} {platform.release()}",
            "platform": platform.platform(),
            "processor": platform.processor() or platform.machine(),
            "architecture": platform.architecture()[0],
            "hostname": platform.node(),
            "python_version": platform.python_version(),
            "python_executable": sys.executable,
            "ram_total_gb": round(psutil.virtual_memory().total / (1024**3), 2),
            "cpu_cores_logical": psutil.cpu_count(logical=True),
            "cpu_cores_physical": psutil.cpu_count(logical=False),
            "cpu_frequency_mhz": psutil.cpu_freq().current if psutil.cpu_freq() else None,
            "boot_time": boot_time.strftime("%Y-%m-%d %H:%M:%S"),
            "uptime_hours": round((datetime.now() - boot_time).total_seconds() / 3600, 2)
        }
    except ImportError:
        return {
            "os": f"{platform.system()} {platform.release()}",
            "platform": platform.platform(),
            "processor": platform.processor() or platform.machine(),
            "architecture": platform.architecture()[0],
            "hostname": platform.node(),
            "python_version": platform.python_version(),
            "python_executable": sys.executable,
            "error": "psutil not available for detailed system info"
        }

def assess_system():
    result = {}
    
    # GROMACS information
    g_installed, g_path = check_gromacs_installed()
    result["gromacs_installed"] = g_installed
    result["gromacs_path"] = g_path
    
    if g_installed:
        result["gromacs_details"] = get_detailed_gromacs_info()
        result["gromacs_version"] = result["gromacs_details"]["version"]
        result["gromacs_gpu_support"] = result["gromacs_details"]["gpu_support"]
    else:
        result["gromacs_details"] = None
        result["gromacs_version"] = None
        result["gromacs_gpu_support"] = False
    
    # GPU information
    gpu_present, gpu_basic_info = check_nvidia_gpu()
    result["gpu_present"] = gpu_present
    result["gpu_basic_info"] = gpu_basic_info
    result["gpu_details"] = get_detailed_gpu_info()
    
    # System information
    result["system_info"] = get_system_info()
    result["memory_usage"] = get_memory_usage()
    result["cpu_usage"] = get_cpu_usage()
    
    # Assessment
    ready = all([g_installed, result["gromacs_gpu_support"], gpu_present])
    result["ready_for_gpu_simulations"] = ready
    result["status"] = "Ready" if ready else "Not Ready"
    result["timestamp"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    
    return result

def print_summary(result):
    # Clear screen and show professional header
    os.system('clear' if os.name == 'posix' else 'cls')
    
    # Main header
    print(f"\n{format_header('GROVERIFIER - GROMACS GPU COMPATIBILITY CHECKER')}")
    print(f"{Colors.DIM}Professional System Assessment Tool for GROMACS GPU Simulations{Colors.RESET}")
    print(f"{Colors.DIM}Scan completed at: {result['timestamp']}{Colors.RESET}\n")
    
    # GROMACS Information Section
    print(format_section("GROMACS INSTALLATION", "🧬"))
    print(format_value("Installation Status", "Installed" if result['gromacs_installed'] else "Not Found", 
                      status=result['gromacs_installed'], indent=1))
    
    if result['gromacs_installed']:
        gromacs = result['gromacs_details']
        print(format_value("Version", gromacs['version'], indent=1))
        print(format_value("Build Date", gromacs['build_date'], indent=1))
        print(format_value("Precision", gromacs['precision'], indent=1))
        print(format_value("SIMD Instructions", gromacs['simd'], indent=1))
        print(format_value("FFT Library", gromacs['fft'], indent=1))
        print(format_value("GPU Support", "Enabled" if gromacs['gpu_support'] else "Disabled", 
                          status=gromacs['gpu_support'], indent=1))
        print(format_value("MPI Support", "Enabled" if gromacs['mpi_support'] else "Disabled", 
                          status=gromacs['mpi_support'], indent=1))
        print(format_value("Executable Path", gromacs.get('path', result['gromacs_path']), indent=1))
    
    print(f"{Colors.BRIGHT_BLUE}└{'─' * 78}┘{Colors.RESET}\n")
    
    # GPU Information Section
    print(format_section("GPU HARDWARE", "🎮"))
    print(format_value("NVIDIA GPU Detected", "Yes" if result['gpu_present'] else "No", 
                      status=result['gpu_present'], indent=1))
    
    if result['gpu_present'] and result['gpu_details']['total_gpus'] > 0:
        gpu_info = result['gpu_details']
        print(format_value("Driver Version", gpu_info['nvidia_driver_version'], indent=1))
        if gpu_info['cuda_version'] != "Not Available":
            print(format_value("CUDA Version", gpu_info['cuda_version'], indent=1))
        print(format_value("Total GPUs", str(gpu_info['total_gpus']), indent=1))
        
        for i, gpu in enumerate(gpu_info['gpus']):
            print(f"\n{Colors.BRIGHT_BLUE}├─{Colors.RESET} {Colors.BRIGHT_YELLOW}GPU {gpu['index']}:{Colors.RESET} {Colors.BRIGHT_WHITE}{gpu['name']}{Colors.RESET}")
            
            # Memory usage with progress bar
            memory_percent = round(gpu['memory_used_mb']/gpu['memory_total_mb']*100, 1) if gpu['memory_total_mb'] > 0 else 0
            memory_bar = format_progress_bar(memory_percent, width=25)
            print(format_value("Memory Usage", f"{gpu['memory_used_mb']:,} / {gpu['memory_total_mb']:,} MB", indent=2))
            print(f"    {Colors.BRIGHT_BLUE}│{Colors.RESET}   {memory_bar}")
            
            # GPU utilization with progress bar
            gpu_util_bar = format_progress_bar(gpu['gpu_utilization_percent'], width=25)
            print(format_value("GPU Utilization", "", indent=2))
            print(f"    {Colors.BRIGHT_BLUE}│{Colors.RESET}   {gpu_util_bar}")
            
            print(format_value("Temperature", f"{gpu['temperature_c']}", "°C", indent=2))
            print(format_value("Power Draw", f"{gpu['power_draw_w']:.1f} / {gpu['power_limit_w']:.0f}", " W", indent=2))
    
    print(f"{Colors.BRIGHT_BLUE}└{'─' * 78}┘{Colors.RESET}\n")
    
    # System Information Section
    print(format_section("SYSTEM SPECIFICATIONS", "💻"))
    sys_info = result['system_info']
    print(format_value("Operating System", sys_info['os'], indent=1))
    print(format_value("Architecture", sys_info['architecture'], indent=1))
    print(format_value("Hostname", sys_info['hostname'], indent=1))
    print(format_value("Processor", sys_info['processor'], indent=1))
    
    if 'cpu_cores_logical' in sys_info:
        print(format_value("CPU Cores", f"{sys_info['cpu_cores_physical']} physical, {sys_info['cpu_cores_logical']} logical", indent=1))
        if sys_info['cpu_frequency_mhz']:
            print(format_value("CPU Frequency", f"{sys_info['cpu_frequency_mhz']:.0f}", " MHz", indent=1))
        print(format_value("System Uptime", f"{sys_info['uptime_hours']:.1f}", " hours", indent=1))
    
    print(format_value("Python Version", f"{sys_info['python_version']}", indent=1))
    print(f"{Colors.BRIGHT_BLUE}└{'─' * 78}┘{Colors.RESET}\n")
    
    # Resource Usage Section
    print(format_section("RESOURCE UTILIZATION", "📊"))
    
    # Memory Usage
    if 'error' not in result['memory_usage']:
        mem = result['memory_usage']
        ram_bar = format_progress_bar(mem['usage_percent'], width=25)
        print(format_value("RAM Usage", f"{mem['used_gb']:.1f} / {mem['total_gb']:.1f} GB", indent=1))
        print(f"  {Colors.BRIGHT_BLUE}│{Colors.RESET}   {ram_bar}")
        print(format_value("Available RAM", f"{mem['available_gb']:.1f}", " GB", indent=1))
        
        if mem['swap_total_gb'] > 0:
            swap_bar = format_progress_bar(mem['swap_usage_percent'], width=25)
            print(format_value("Swap Usage", f"{mem['swap_used_gb']:.1f} / {mem['swap_total_gb']:.1f} GB", indent=1))
            print(f"  {Colors.BRIGHT_BLUE}│{Colors.RESET}   {swap_bar}")
    
    # CPU Usage
    if 'error' not in result['cpu_usage']:
        cpu = result['cpu_usage']
        cpu_bar = format_progress_bar(cpu['usage_percent'], width=25)
        print(format_value("CPU Usage", "", indent=1))
        print(f"  {Colors.BRIGHT_BLUE}│{Colors.RESET}   {cpu_bar}")
        
        if cpu['load_average']:
            print(format_value("Load Average", f"{cpu['load_average'][0]:.2f}, {cpu['load_average'][1]:.2f}, {cpu['load_average'][2]:.2f}", " (1m, 5m, 15m)", indent=1))
    
    print(f"{Colors.BRIGHT_BLUE}└{'─' * 78}┘{Colors.RESET}\n")
    
    # Assessment Section
    print(format_section("SYSTEM ASSESSMENT", "🎯"))
    
    if result['ready_for_gpu_simulations']:
        print(f"  {Colors.BRIGHT_BLUE}│{Colors.RESET} {Colors.BG_GREEN}{Colors.BRIGHT_WHITE} ✓ READY FOR GPU SIMULATIONS {Colors.RESET}")
        print(f"  {Colors.BRIGHT_BLUE}│{Colors.RESET} {Colors.GREEN}Your system is optimally configured for GROMACS GPU acceleration{Colors.RESET}")
    else:
        print(f"  {Colors.BRIGHT_BLUE}│{Colors.RESET} {Colors.BG_RED}{Colors.BRIGHT_WHITE} ✗ NOT READY {Colors.RESET}")
        print(f"  {Colors.BRIGHT_BLUE}│{Colors.RESET}")
        print(f"  {Colors.BRIGHT_BLUE}│{Colors.RESET} {Colors.BRIGHT_YELLOW}Recommendations:{Colors.RESET}")
        
        if not result['gromacs_installed']:
            print(f"  {Colors.BRIGHT_BLUE}│{Colors.RESET}   {Colors.YELLOW}•{Colors.RESET} Install GROMACS with GPU support")
        elif not result['gromacs_gpu_support']:
            print(f"  {Colors.BRIGHT_BLUE}│{Colors.RESET}   {Colors.YELLOW}•{Colors.RESET} Reinstall GROMACS with CUDA/OpenCL support")
        if not result['gpu_present']:
            print(f"  {Colors.BRIGHT_BLUE}│{Colors.RESET}   {Colors.YELLOW}•{Colors.RESET} Install NVIDIA GPU drivers")
            print(f"  {Colors.BRIGHT_BLUE}│{Colors.RESET}   {Colors.YELLOW}•{Colors.RESET} Install CUDA toolkit")
    
    print(f"{Colors.BRIGHT_BLUE}└{'─' * 78}┘{Colors.RESET}\n")
    
    # Footer
    print(f"{Colors.DIM}{'─' * 80}{Colors.RESET}")
    print(f"{Colors.DIM}groverifier v1.1.0 | Professional GROMACS GPU Assessment Tool{Colors.RESET}")
    print(f"{Colors.DIM}For support: {Colors.UNDERLINE}dev.vishalravi@gmail.com{Colors.RESET}\n")

def print_startup_animation():
    """Display professional startup animation"""
    import time
    
    # Clear screen
    os.system('clear' if os.name == 'posix' else 'cls')
    
    # Animated header
    logo_lines = [
        f"{Colors.BRIGHT_CYAN}     ╔═══════════════════════════════════════════════════════════╗{Colors.RESET}",
        f"{Colors.BRIGHT_CYAN}     ║                                                           ║{Colors.RESET}",
        f"{Colors.BRIGHT_CYAN}     ║     {Colors.BRIGHT_WHITE}🧬 GROVERIFIER{Colors.RESET} {Colors.BRIGHT_CYAN}                                      ║{Colors.RESET}",
        f"{Colors.BRIGHT_CYAN}     ║     {Colors.WHITE}Professional GROMACS GPU Assessment Tool{Colors.RESET} {Colors.BRIGHT_CYAN}        ║{Colors.RESET}",
        f"{Colors.BRIGHT_CYAN}     ║                                                           ║{Colors.RESET}",
        f"{Colors.BRIGHT_CYAN}     ╚═══════════════════════════════════════════════════════════╝{Colors.RESET}",
    ]
    
    for line in logo_lines:
        print(line)
        time.sleep(0.1)
    
    print(f"\n{Colors.DIM}Initializing system assessment...{Colors.RESET}")
    
    # Progress bar animation
    steps = ["Checking GROMACS installation", "Analyzing GPU hardware", "Gathering system information", "Measuring resource usage"]
    
    for i, step in enumerate(steps):
        print(f"{Colors.BRIGHT_BLUE}[{i+1}/4]{Colors.RESET} {step}...", end="", flush=True)
        
        # Animated dots
        for _ in range(3):
            time.sleep(0.3)
            print(".", end="", flush=True)
        
        print(f" {Colors.BRIGHT_GREEN}✓{Colors.RESET}")
        time.sleep(0.2)
    
    print(f"\n{Colors.BRIGHT_GREEN}Assessment complete!{Colors.RESET} Generating report...\n")
    time.sleep(0.5)

def main():
    if platform.system() == "Windows":
        print(f"{Colors.BRIGHT_RED}❌ Windows Detected{Colors.RESET}")
        print(f"{Colors.YELLOW}This tool is designed for Linux systems where GROMACS is optimally supported.{Colors.RESET}")
        print(f"{Colors.BRIGHT_CYAN}💡 Recommendation:{Colors.RESET} Use WSL (Windows Subsystem for Linux) or a native Linux environment.")
        sys.exit(1)
    
    parser = argparse.ArgumentParser(
        description=f"{Colors.BRIGHT_CYAN}groverifier{Colors.RESET}: Professional GROMACS GPU Compatibility Checker",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=f"""
{Colors.BOLD}Examples:{Colors.RESET}
  {Colors.GREEN}groverifier{Colors.RESET}                    # Show detailed professional assessment
  {Colors.GREEN}groverifier --json{Colors.RESET}             # Output in JSON format for automation
  {Colors.GREEN}groverifier --json --compact{Colors.RESET}   # Compact JSON output
  {Colors.GREEN}groverifier --no-animation{Colors.RESET}     # Skip startup animation

{Colors.BOLD}Features:{Colors.RESET}
  • Professional visual presentation with color coding
  • Comprehensive GROMACS installation analysis
  • Real-time GPU monitoring and utilization
  • System resource usage with progress bars
  • JSON export for CI/CD integration
        """
    )
    parser.add_argument("--json", action="store_true", 
                       help="Output results in JSON format for automation")
    parser.add_argument("--compact", action="store_true", 
                       help="Compact JSON output (no indentation)")
    parser.add_argument("--no-animation", action="store_true", 
                       help="Skip startup animation for faster execution")
    parser.add_argument("--version", action="version", 
                       version=f"{Colors.BRIGHT_CYAN}groverifier{Colors.RESET} v1.1.0 - Professional GROMACS GPU Assessment Tool")
    
    args = parser.parse_args()
    
    # Show startup animation unless disabled or JSON output
    if not args.json and not args.no_animation:
        print_startup_animation()
    
    result = assess_system()
    
    if args.json:
        indent = None if args.compact else 2
        print(json.dumps(result, indent=indent))
    else:
        print_summary(result)

def cli_main():
    main()

if __name__ == "__main__":
    main()
