"""
JSEye Tool Installer - Auto-install required external tools
"""

import os
import subprocess
import shutil
from pathlib import Path
from rich.console import Console
from rich.progress import Progress, SpinnerColumn, TextColumn

console = Console()

REQUIRED_TOOLS = {
    "gau": {
        "check_cmd": ["gau", "--help"],
        "install_cmd": ["go", "install", "github.com/lc/gau/v2/cmd/gau@latest"],
        "requires": "go"
    },
    "waybackurls": {
        "check_cmd": ["waybackurls", "-h"],
        "install_cmd": ["go", "install", "github.com/tomnomnom/waybackurls@latest"],
        "requires": "go"
    },
    "hakrawler": {
        "check_cmd": ["hakrawler", "-h"],
        "install_cmd": ["go", "install", "github.com/hakluke/hakrawler@latest"],
        "requires": "go"
    },
    "katana": {
        "check_cmd": ["katana", "-h"],
        "install_cmd": ["go", "install", "github.com/projectdiscovery/katana/cmd/katana@latest"],
        "requires": "go"
    },
    "subjs": {
        "check_cmd": ["subjs", "-h"],
        "install_cmd": ["go", "install", "github.com/lc/subjs@latest"],
        "requires": "go"
    },
    "linkfinder": {
        "check_cmd": ["python3", "-c", "import linkfinder"],
        "install_cmd": ["pip3", "install", "linkfinder"],
        "requires": "python3"
    },
    "mantra": {
        "check_cmd": ["mantra", "--help"],
        "install_cmd": ["go", "install", "github.com/MrEmpy/mantra@latest"],
        "requires": "go"
    }
}

def check_system_requirements():
    """Check if Go and Node.js are installed"""
    requirements = {
        "go": shutil.which("go") is not None,
        "node": shutil.which("node") is not None,
        "python3": shutil.which("python3") is not None,
        "pip3": shutil.which("pip3") is not None
    }
    
    missing = [req for req, available in requirements.items() if not available]
    
    if missing:
        console.print(f"[red]Missing system requirements: {', '.join(missing)}[/red]")
        console.print("[yellow]Please install the missing requirements:[/yellow]")
        
        if "go" in missing:
            console.print("  • Go: https://golang.org/doc/install")
        if "node" in missing:
            console.print("  • Node.js: https://nodejs.org/")
        if "python3" in missing or "pip3" in missing:
            console.print("  • Python3 + pip3: https://python.org/")
            
        return False
    
    return True

def is_tool_installed(tool_name, check_cmd):
    """Check if a tool is installed and working"""
    try:
        result = subprocess.run(
            check_cmd,
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL,
            timeout=10
        )
        return result.returncode == 0
    except (subprocess.TimeoutExpired, FileNotFoundError):
        return False

def install_tool(tool_name, install_cmd):
    """Install a single tool"""
    try:
        console.print(f"[yellow]Installing {tool_name}...[/yellow]")
        
        result = subprocess.run(
            install_cmd,
            capture_output=True,
            text=True,
            timeout=300  # 5 minutes timeout
        )
        
        if result.returncode == 0:
            console.print(f"[green]✓ {tool_name} installed successfully[/green]")
            return True
        else:
            console.print(f"[red]✗ Failed to install {tool_name}[/red]")
            console.print(f"[red]Error: {result.stderr}[/red]")
            return False
            
    except subprocess.TimeoutExpired:
        console.print(f"[red]✗ Installation of {tool_name} timed out[/red]")
        return False
    except Exception as e:
        console.print(f"[red]✗ Error installing {tool_name}: {e}[/red]")
        return False

def check_and_install_tools():
    """Check and install all required tools"""
    
    # First check system requirements
    if not check_system_requirements():
        return False
    
    console.print("[cyan]Checking external tools...[/cyan]")
    
    missing_tools = []
    installed_tools = []
    
    # Check which tools are missing
    for tool_name, config in REQUIRED_TOOLS.items():
        if is_tool_installed(tool_name, config["check_cmd"]):
            installed_tools.append(tool_name)
            console.print(f"[green]✓ {tool_name}[/green]")
        else:
            missing_tools.append(tool_name)
            console.print(f"[yellow]✗ {tool_name} (missing)[/yellow]")
    
    if not missing_tools:
        console.print("[green]All tools are already installed![/green]")
        return True
    
    # Install missing tools
    console.print(f"\n[yellow]Installing {len(missing_tools)} missing tools...[/yellow]")
    
    failed_installs = []
    
    with Progress(
        SpinnerColumn(),
        TextColumn("[progress.description]{task.description}"),
        console=console
    ) as progress:
        
        for tool_name in missing_tools:
            config = REQUIRED_TOOLS[tool_name]
            
            task = progress.add_task(f"Installing {tool_name}...", total=None)
            
            if install_tool(tool_name, config["install_cmd"]):
                progress.update(task, description=f"✓ {tool_name} installed")
            else:
                failed_installs.append(tool_name)
                progress.update(task, description=f"✗ {tool_name} failed")
    
    if failed_installs:
        console.print(f"\n[red]Failed to install: {', '.join(failed_installs)}[/red]")
        console.print("[yellow]You may need to install these tools manually[/yellow]")
        return False
    
    console.print("\n[green]All tools installed successfully![/green]")
    return True

def get_install_cache_path():
    """Get path for install cache"""
    cache_dir = Path.home() / ".jseye"
    cache_dir.mkdir(exist_ok=True)
    return cache_dir / "install_cache.txt"

def is_install_cached():
    """Check if tools were previously installed"""
    cache_file = get_install_cache_path()
    return cache_file.exists()

def cache_install_state():
    """Cache that tools have been installed"""
    cache_file = get_install_cache_path()
    cache_file.write_text("installed")

if __name__ == "__main__":
    check_and_install_tools()