import os
import sys
import json
import shutil
import getpass
import subprocess
import platform
import urllib.request
import urllib.error

# Configurações de caminhos por OS
IS_WINDOWS = platform.system() == "Windows"

# Credenciais do Cloud Relay (mesmos caminhos usados pelo agent.py)
CLI_DIR = os.path.join(os.path.expanduser('~'), '.gemini', 'antigravity-cli')
CREDENTIALS_FILE = os.path.join(CLI_DIR, 'cache', 'credentials.json')
DEFAULT_RELAY_URL = "https://antigravity-remote.siamac.com.br"

if IS_WINDOWS:
    INSTALL_DIR = os.path.expandvars(r'%LOCALAPPDATA%\AntigravityAgent')
    STARTUP_DIR = os.path.expandvars(r'%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup')
else:
    # macOS / Linux (macOS prioritário)
    INSTALL_DIR = os.path.expanduser('~/Library/Application Support/AntigravityAgent')
    STARTUP_DIR = os.path.expanduser('~/Library/LaunchAgents')

def kill_agent_processes():
    print("[*] Finalizando processos do agente em execução...")
    if IS_WINDOWS:
        try:
            cmd = 'powershell -Command "Get-CimInstance Win32_Process -Filter \\"name like \'python%.exe\'\\" | Where-Object { $_.CommandLine -like \'*agent.py*\' -or $_.CommandLine -like \'*agent_watchdog.py*\' } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force }"'
            subprocess.run(cmd, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
            print("    Processos finalizados via PowerShell.")
        except Exception as e:
            print(f"[-] Erro ao finalizar processos no Windows: {e}")
    else:
        try:
            subprocess.run(["pkill", "-f", "agent.py"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
            subprocess.run(["pkill", "-f", "agent_watchdog.py"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
            print("    Processos finalizados.")
        except Exception as e:
            print(f"[-] Erro ao finalizar processos: {e}")

def install_dependencies():
    dependencies = ['pystray', 'pillow', 'python-socketio', 'requests', 'websocket-client']
    print("[*] Verificando dependencias do Python...")
    for dep in dependencies:
        try:
            if dep == 'pillow':
                import PIL
            elif dep == 'python-socketio':
                import socketio
            elif dep == 'websocket-client':
                import websocket
            else:
                __import__(dep)
            print(f"    - {dep}: OK")
        except ImportError:
            print(f"    - {dep}: Ausente. Instalando...")
            try:
                subprocess.check_call([sys.executable, "-m", "pip", "install", dep])
                print(f"    - {dep}: Instalado com sucesso!")
            except Exception:
                # Python do Homebrew/macOS recente bloqueia pip global (PEP 668);
                # tenta novamente instalando apenas para o usuário.
                try:
                    subprocess.check_call([sys.executable, "-m", "pip", "install", "--user", "--break-system-packages", dep])
                    print(f"    - {dep}: Instalado com sucesso (modo usuário)!")
                except Exception as e:
                    print(f"[-] Erro ao instalar {dep}: {e}")

def configure_credentials():
    """Faz o login no Cloud Relay durante a instalação e salva as credenciais.

    Essencial no macOS, onde o agente roda headless (launchd) e não tem a janela
    de login do tray. Usa apenas a biblioteca padrão (urllib), pois roda antes de
    qualquer dependência estar garantida.
    """
    print("\n[*] Configuração de login no Cloud Relay")
    if not sys.stdin.isatty():
        print("    Terminal não interativo; pulando a configuração de login.")
        return

    if os.path.exists(CREDENTIALS_FILE):
        try:
            ans = input("    Já existem credenciais salvas. Deseja refazer o login? (s/N): ").strip().lower()
        except EOFError:
            return
        if ans != 's':
            print("    Mantendo credenciais existentes.")
            return

    for _attempt in range(3):
        try:
            url = input(f"    URL do Cloud Relay [{DEFAULT_RELAY_URL}]: ").strip() or DEFAULT_RELAY_URL
            if not url.startswith('http://') and not url.startswith('https://'):
                url = 'https://' + url
            user = input("    Usuário: ").strip()
            pwd = getpass.getpass("    Senha: ")
        except EOFError:
            return
        if not user or not pwd:
            print("    [-] Usuário e senha são obrigatórios.")
            continue
        try:
            req = urllib.request.Request(
                url.rstrip('/') + '/api/login',
                data=json.dumps({"username": user, "password": pwd}).encode('utf-8'),
                headers={'Content-Type': 'application/json'},
                method='POST'
            )
            with urllib.request.urlopen(req, timeout=10) as resp:
                data = json.loads(resp.read().decode('utf-8'))
            token = data.get('token')
            if not token:
                raise ValueError("Resposta do servidor sem token.")
            os.makedirs(os.path.dirname(CREDENTIALS_FILE), exist_ok=True)
            with open(CREDENTIALS_FILE, 'w', encoding='utf-8') as f:
                json.dump({"server_url": url, "username": user, "token": token}, f, indent=4)
            print("    [+] Login realizado com sucesso! Credenciais salvas.")
            return
        except urllib.error.HTTPError as e:
            print(f"    [-] Falha no login (HTTP {e.code}). Verifique usuário e senha.")
        except Exception as e:
            print(f"    [-] Erro ao conectar ao Cloud Relay: {e}")
    print("    [-] Não foi possível fazer o login agora. O agente pedirá login na primeira execução.")

def copy_agent_files():
    print(f"[*] Instalando arquivos em: {INSTALL_DIR}")
    os.makedirs(INSTALL_DIR, exist_ok=True)
    
    src_dir = os.path.dirname(os.path.abspath(__file__))
    ignore_files = ['install.py', 'agent_w.log', 'agent_system.log', 'agent_system.log.bak', '.git', '__pycache__', 'test.jpg']
    
    copied_count = 0
    for item in os.listdir(src_dir):
        if item in ignore_files:
            continue
        
        src_path = os.path.join(src_dir, item)
        dest_path = os.path.join(INSTALL_DIR, item)
        
        try:
            if os.path.isdir(src_path):
                shutil.copytree(src_path, dest_path, dirs_exist_ok=True)
            else:
                shutil.copy2(src_path, dest_path)
            print(f"    -> Copiado: {item}")
            copied_count += 1
        except Exception as e:
            print(f"[-] Erro ao copiar {item}: {e}")
            
    print(f"[+] {copied_count} itens instalados com sucesso!")

def setup_startup():
    if IS_WINDOWS:
        vbs_path = os.path.join(STARTUP_DIR, "AntigravityAgent.vbs")
        vbs_watchdog_path = os.path.join(STARTUP_DIR, "AntigravityWatchdog.vbs")
        lnk_path = os.path.join(STARTUP_DIR, "AntigravityAgent.lnk")
        lnk_watchdog_path = os.path.join(STARTUP_DIR, "AntigravityWatchdog.lnk")
        
        # Remove atalhos antigos se existirem para evitar duplicados ou conflitos
        for path in (vbs_path, vbs_watchdog_path, lnk_path, lnk_watchdog_path):
            if os.path.exists(path):
                try:
                    os.remove(path)
                except Exception:
                    pass
                    
        agent_py_path = os.path.join(INSTALL_DIR, "agent.py")
        agent_watchdog_path = os.path.join(INSTALL_DIR, "agent_watchdog.py")
        print(f"[*] Configurando inicializacao automatica no Windows...")
        pythonw_path = sys.executable.lower().replace("python.exe", "pythonw.exe")
        vbs_content = f'''Set WshShell = CreateObject("WScript.Shell")
WshShell.Run """{pythonw_path}"" ""{agent_py_path}""", 0, False
'''
        vbs_watchdog_content = f'''Set WshShell = CreateObject("WScript.Shell")
WshShell.Run """{pythonw_path}"" ""{agent_watchdog_path}""", 0, False
'''
        try:
            os.makedirs(STARTUP_DIR, exist_ok=True)
            with open(vbs_path, "w", encoding="utf-8") as f:
                f.write(vbs_content)
            with open(vbs_watchdog_path, "w", encoding="utf-8") as f:
                f.write(vbs_watchdog_content)
            print("    Atalhos VBS de inicializacao silenciosa criados com sucesso!")
            return True
        except Exception as e:
            print(f"[-] Erro ao configurar inicializacao no Windows: {e}")
            return False
    else:
        # macOS Launch Agent
        plist_path = os.path.join(STARTUP_DIR, "com.antigravity.remoteagent.plist")
        agent_py_path = os.path.join(INSTALL_DIR, "agent.py")
        python_exe = sys.executable
        
        print(f"[*] Configurando inicializacao automatica no macOS em: {plist_path}")
        plist_content = f'''<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.antigravity.remoteagent</string>
    <key>ProgramArguments</key>
    <array>
        <string>{python_exe}</string>
        <string>{agent_py_path}</string>
        <string>--headless</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>WorkingDirectory</key>
    <string>{INSTALL_DIR}</string>
    <key>StandardOutPath</key>
    <string>{INSTALL_DIR}/agent_stdout.log</string>
    <key>StandardErrorPath</key>
    <string>{INSTALL_DIR}/agent_stderr.log</string>
</dict>
</plist>
'''
        try:
            os.makedirs(STARTUP_DIR, exist_ok=True)
            with open(plist_path, "w", encoding="utf-8") as f:
                f.write(plist_content)
            
            # Da permissao de leitura/escrita correta para launchd carregar
            os.chmod(plist_path, 0o644)
            
            # Carrega o Launch Agent
            print("    Registrando Launch Agent no sistema...")
            uid = os.getuid() if hasattr(os, 'getuid') else 0
            subprocess.run(['launchctl', 'bootout', f'gui/{uid}', plist_path], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
            subprocess.run(['launchctl', 'unload', plist_path], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
            
            res = subprocess.run(['launchctl', 'bootstrap', f'gui/{uid}', plist_path], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
            if res.returncode == 0:
                print("    Launch Agent registrado e ativado com sucesso!")
            else:
                res_legacy = subprocess.run(['launchctl', 'load', plist_path])
                if res_legacy.returncode == 0:
                    print("    Launch Agent registrado via load legado com sucesso!")
                else:
                    print("    Launch Agent criado, mas falhou ao registrar via launchctl (pode requerer login interativo).")
            return True
        except Exception as e:
            print(f"[-] Erro ao configurar inicializacao no macOS: {e}")
            return False

def start_installed_agent():
    print("[*] Iniciando o agente e o watchdog recem-instalados em segundo plano...")
    agent_py_path = os.path.join(INSTALL_DIR, "agent.py")
    agent_watchdog_path = os.path.join(INSTALL_DIR, "agent_watchdog.py")
    try:
        if IS_WINDOWS:
            pythonw_path = sys.executable.lower().replace("python.exe", "pythonw.exe")
            # DETACHED_PROCESS (0x00000008) + CREATE_NEW_PROCESS_GROUP (0x00000200)
            flags = 0x00000008 | 0x00000200
            subprocess.Popen([pythonw_path, agent_py_path], cwd=INSTALL_DIR, close_fds=True, creationflags=flags)
            subprocess.Popen([pythonw_path, agent_watchdog_path], cwd=INSTALL_DIR, close_fds=True, creationflags=flags)
        else:
            # macOS: executa via python3 normal mas desassociado do terminal e com flag headless
            with open(os.devnull, 'r+') as devnull:
                subprocess.Popen([sys.executable, agent_py_path, '--headless'], cwd=INSTALL_DIR, stdin=devnull, stdout=devnull, stderr=devnull, start_new_session=True)
                subprocess.Popen([sys.executable, agent_watchdog_path, '--headless'], cwd=INSTALL_DIR, stdin=devnull, stdout=devnull, stderr=devnull, start_new_session=True)
        print("[+] Agente e watchdog iniciados com sucesso!")
    except Exception as e:
        print(f"[-] Erro ao iniciar o agente/watchdog: {e}")

def main():
    print("=" * 60)
    print("      Instalador do Antigravity Remote Agent")
    print(f"      Sistema Operacional: {platform.system()}")
    print("=" * 60)
    
    kill_agent_processes()
    install_dependencies()
    copy_agent_files()
    configure_credentials()
    setup_startup()
    start_installed_agent()
    
    print("\n=== Instalacao Concluida! ===")
    if IS_WINDOWS:
        print("O agente foi configurado para iniciar silenciosamente junto com o Windows.")
    else:
        print("O agente foi configurado para iniciar silenciosamente junto com o macOS (Launch Agent).")
    print("Voce ja pode fechar esta janela.")

if __name__ == "__main__":
    main()
