#!/usr/bin/env python3
"""
Bootstrap Stack - Inicialização Automática do Ecossistema
Autor: Roberto Cezar / Orquestração LOBO
Descrição: Script unificado para subir o Proxy Composio, Servidor de Arquivos e Túnel Tailscale.
"""

import os
import sys
import subprocess
import platform
import time
import shutil

# Cores para o terminal
class C:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKCYAN = '\033[96m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'

def print_banner():
    os.system('cls' if os.name == 'nt' else 'clear')
    print(f"{C.OKCYAN}{C.BOLD}")
    print("=" * 60)
    print("      BOOTSTRAP STACK - INICIALIZAÇÃO AUTOMÁTICA      ")
    print("=" * 60)
    print(f"{C.ENDC}")

def check_dependencies():
    print(f"{C.OKBLUE}[*] Verificando dependências do sistema...{C.ENDC}")
    
    # 1. Verifica Python
    if sys.version_info < (3, 8):
        print(f"{C.FAIL}[X] Python 3.8+ é necessário.{C.ENDC}")
        sys.exit(1)
    print(f"  [OK] Python {platform.python_version()}")

    # 2. Verifica Tailscale
    if not shutil.which("tailscale"):
        print(f"{C.WARNING}  [!] Tailscale não encontrado no PATH.{C.ENDC}")
        print(f"{C.WARNING}      O Túnel não será iniciado automaticamente.{C.ENDC}")
        return False
    
    # 3. Verifica UV (para o Composio)
    if not shutil.which("uv"):
        print(f"{C.WARNING}  [!] 'uv' não encontrado no PATH. Usando Python padrão para o proxy.{C.ENDC}")
        return True # Permite continuar, mas avisa

    print(f"  [OK] Tailscale e UV encontrados.")
    return True

def find_composio_proxy():
    print(f"{C.OKBLUE}[*] Procurando o composio_mcp_proxy.py...{C.ENDC}")
    
    # Caminhos comuns a serem testados
    possible_paths = [
        os.path.expanduser("~/composio-mcp-proxy/composio_mcp_proxy.py"),
        os.path.expanduser("~\\Desktop\\NINJA\\composio-mcp-proxy\\composio-mcp-proxy\\composio_mcp_proxy.py"),
        "C:\\Users\\Usuario\\composio-mcp-proxy\\composio_mcp_proxy.py",
        "./composio-mcp-proxy/composio_mcp_proxy.py"
    ]
    
    for path in possible_paths:
        if os.path.exists(path):
            print(f"  [OK] Encontrado em: {path}")
            return path
            
    print(f"{C.WARNING}  [!] Arquivo do Proxy Composio não encontrado nos caminhos padrão.{C.ENDC}")
    return None

def start_services():
    processes = []
    
    # 1. Subindo Servidor HTTP (Porta 8080)
    print(f"\n{C.OKGREEN}[+] Subindo Servidor HTTP de arquivos na porta 8080...{C.ENDC}")
    try:
        http_server = subprocess.Popen([sys.executable, "-m", "http.server", "8080"])
        processes.append(("HTTP Server", http_server))
    except Exception as e:
        print(f"{C.FAIL}[X] Erro ao subir HTTP Server: {e}{C.ENDC}")

    # 2. Subindo Proxy Composio
    proxy_path = find_composio_proxy()
    if proxy_path:
        print(f"\n{C.OKGREEN}[+] Subindo Proxy Composio...{C.ENDC}")
        proxy_dir = os.path.dirname(proxy_path)
        proxy_filename = os.path.basename(proxy_path)
        
        cmd = ["uv", "run", "python", proxy_filename] if shutil.which("uv") else [sys.executable, proxy_filename]
        
        try:
            # Nota: O proxy pode precisar de variáveis de ambiente. 
            # Aqui assumimos que ele já está configurado ou usa .env local.
            composio_proc = subprocess.Popen(cmd, cwd=proxy_dir)
            processes.append(("Composio Proxy", composio_proc))
        except Exception as e:
            print(f"{C.FAIL}[X] Erro ao subir Proxy Composio: {e}{C.ENDC}")
    
    # 3. Subindo Tailscale Funnel
    print(f"\n{C.OKGREEN}[+] Subindo Tailscale Funnel para a porta 8080...{C.ENDC}")
    try:
        # Rodamos o funnel em background
        funnel_proc = subprocess.Popen(["tailscale", "funnel", "8080"])
        processes.append(("Tailscale Funnel", funnel_proc))
    except Exception as e:
        print(f"{C.WARNING}[!] Erro ao subir Tailscale Funnel: {e}{C.ENDC}")

    return processes

def display_summary():
    print(f"\n{C.OKCYAN}{C.BOLD}=" * 60)
    print("                  STACK OPERACIONAL                   ")
    print("=" * 60 + f"{C.ENDC}")
    print(f"{C.BOLD}1. BDS (Better DeepSeek) - Servidor de Arquivos:{C.ENDC}")
    print(f"   O Servidor local está rodando na porta 8080.")
    print(f"   O Tailscale Funnel deve fornecer uma URL HTTPS.")
    print(f"   Copie a URL gerada (ex: https://desktop...ts.net/) e adicione")
    print(f"   o nome do arquivo que deseja ler (ex: /retorno.md)")
    
    print(f"\n{C.BOLD}2. Composio MCP (Proxy Local):{C.ENDC}")
    print(f"   O proxy deve estar rodando (geralmente na porta 18000 ou 8000).")
    print(f"   Vá no painel do BDS > MCP Servers e aponte para o localhost correto.")
    
    print(f"\n{C.WARNING}AVISO: Não feche esta janela. Pressione Ctrl+C para encerrar todos os serviços.{C.ENDC}")
    print(f"{C.OKCYAN}=" * 60 + f"{C.ENDC}")

def main():
    print_banner()
    check_dependencies()
    
    services = start_services()
    
    if not services:
        print(f"\n{C.FAIL}[X] Nenhum serviço pôde ser iniciado. Verifique os erros acima.{C.ENDC}")
        sys.exit(1)
        
    time.sleep(3) # Aguarda os serviços subirem
    display_summary()
    
    try:
        # Mantém o script rodando e monitorando
        while True:
            time.sleep(1)
            # Verifica se algum processo morreu inesperadamente
            for name, proc in services:
                if proc.poll() is not None:
                    print(f"{C.WARNING}[!] O serviço '{name}' foi encerrado.{C.ENDC}")
    except KeyboardInterrupt:
        print(f"\n{C.FAIL}[!] Encerrando todos os serviços e limpando a stack...{C.ENDC}")
        for name, proc in services:
            proc.terminate()
            print(f"  - {name} finalizado.")
        print(f"{C.OKGREEN}Stack encerrada com sucesso.{C.ENDC}")

if __name__ == "__main__":
    main()
