import os
import shutil

def find_gam_executable() -> str:
    """Attempt to find the GAM executable in common locations or system PATH."""
    env_path = os.environ.get("GAM_EXECUTABLE_PATH")
    if env_path:
        return env_path
        
    system_gam = shutil.which('gam')
    if system_gam:
        return system_gam
        
    home_dir = os.path.expanduser('~')
    
    # Common installation paths for GAM and GAMADV-XTD3 across Windows/Mac/Linux
    common_paths = [
        # Mac/Linux standard installer paths
        os.path.join(home_dir, 'bin', 'gam', 'gam'),
        os.path.join(home_dir, 'bin', 'gam7', 'gam'),
        os.path.join(home_dir, 'bin', 'gamadv-xtd3', 'gam'),
        
        # Mac/Linux Homebrew or global paths
        '/usr/local/bin/gam',
        '/opt/homebrew/bin/gam',
        '/usr/bin/gam',
        
        # Windows standard paths
        'C:\\GAM\\gam.exe',
        'C:\\GAM7\\gam.exe',
        'C:\\GAMADV-XTD3\\gam.exe',
        os.path.join(home_dir, 'GAM', 'gam.exe'),
        os.path.join(home_dir, 'GAM7', 'gam.exe'),
        os.path.join(home_dir, 'GAMADV-XTD3', 'gam.exe')
    ]
    
    for path in common_paths:
        if os.path.exists(path) and os.access(path, os.X_OK):
            return path
            
    return "gam"

def find_gam_cfg_dir(executable_path: str) -> str | None:
    """
    Attempt to find the GAM configuration directory.
    If GAM_CFG_DIR is set, use it.
    Check common configuration directories like ~/.gam.
    Otherwise, fallback to the directory containing the resolved gam executable,
    as that is the default behavior for GAM if GAMCFGDIR is not set.
    """
    env_cfg = os.environ.get("GAM_CFG_DIR")
    if env_cfg:
        return env_cfg
        
    home_dir = os.path.expanduser('~')
    common_cfg_paths = [
        os.path.join(home_dir, '.gam'),
        os.path.join(home_dir, '.gamadv-xtd3')
    ]
    
    for path in common_cfg_paths:
        if os.path.exists(path) and os.path.isdir(path):
            if os.path.exists(os.path.join(path, 'gam.cfg')) or os.path.exists(os.path.join(path, 'client_secrets.json')):
                return path
                
    if executable_path and executable_path != "gam" and os.path.exists(executable_path):
        return os.path.dirname(os.path.abspath(executable_path))
        
    return None

GAM_EXECUTABLE_PATH: str = find_gam_executable()
GAM_CFG_DIR = find_gam_cfg_dir(GAM_EXECUTABLE_PATH)

def execute_gam(args: list[str], max_output_lines: int = 200) -> str:
    """
    Executes a GAM command and returns bounded output.
    Truncates stdout at max_output_lines to prevent context overflow.
    Always includes stderr for error visibility.
    """
    import subprocess, os
    cmd = [GAM_EXECUTABLE_PATH] + args
    env = os.environ.copy()
    if GAM_CFG_DIR:
        env["GAMCFGDIR"] = GAM_CFG_DIR
    try:
        result = subprocess.run(cmd, env=env, capture_output=True, text=True, check=False)
        output = []
        if result.stdout:
            lines = result.stdout.strip().splitlines()
            if len(lines) > max_output_lines:
                lines = lines[:max_output_lines]
                lines.append(
                    f"\n[OUTPUT TRUNCATED: showing first {max_output_lines} lines. "
                    f"Use redirect to a Google Sheet for full results.]"
                )
            output.append("STDOUT:\n" + "\n".join(lines))
        if result.stderr:
            output.append(f"STDERR:\n{result.stderr.strip()}")
        if not output:
            return f"Command completed with exit code {result.returncode}, no output produced."
        return "\n\n".join(output)
    except FileNotFoundError:
        return f"ERROR: GAM executable not found at '{GAM_EXECUTABLE_PATH}'."
    except Exception as e:
        return f"ERROR: {str(e)}"
