import os
import platform
import sys
import signal
import threading
import time
from pathlib import Path

class Cores:
    """Classe para definir cores para saída no terminal."""
    VERDE_OK = '\033[92m'
    AVISO = '\033[93m'
    ERRO = '\033[91m'
    AZUL = '\033[94m'
    FIM = '\033[0m'

def mostrar_spinner(mensagem, evento_concluido):
    """
    Mostra um spinner de carregamento na linha de comando.

    Args:
        mensagem (str): A mensagem a ser exibida junto com o spinner.
        evento_concluido (threading.Event): Evento que sinaliza a conclusão do comando.
    """
    spinner = ['|', '/', '-', '\\']
    idx = 0
    while not evento_concluido.is_set():
        print(f"\r{Cores.AZUL}{mensagem} {spinner[idx]}{Cores.FIM}", end='', flush=True)
        idx = (idx + 1) % len(spinner)
        time.sleep(0.1)
    print("\r" + " " * (len(mensagem) + 2), end='\r')

def is_entry_in_file(file_path, entry):
    """
    Verifica se uma entrada já existe no arquivo.

    Args:
        file_path (str): Caminho do arquivo.
        entry (str): Entrada a ser verificada.

    Returns:
        bool: True se a entrada existir no arquivo, False caso contrário.
    """
    with open(file_path, 'r') as file:
        for line in file:
            if entry in line:
                return True
    return False

def add_entries_to_hosts(entries, hosts_path):
    """
    Adiciona entradas ao ficheiro hosts se elas não existirem.

    Args:
        entries (list): Lista de entradas a serem adicionadas.
        hosts_path (str): Caminho do ficheiro hosts.
    
    Returns:
        list: Lista de entradas que foram adicionadas.
    """
    added_entries = []
    with open(hosts_path, 'a') as file:
        for entry in entries:
            if not is_entry_in_file(hosts_path, entry):
                file.write(entry + "\n")
                added_entries.append(entry)
    return added_entries

def main():
    """
    Função principal que adiciona entradas ao ficheiro hosts.
    """
    def interromper_processo(signal_received, frame):
        evento_concluido.set()
        print(f"\n{Cores.AVISO}Processo interrompido pelo utilizador.{Cores.FIM}")
        sys.exit(0)

    signal.signal(signal.SIGINT, interromper_processo)
    signal.signal(signal.SIGTERM, interromper_processo)

    hosts_path = "C:\\Windows\\System32\\drivers\\etc\\hosts" if platform.system() == "Windows" else "/etc/hosts"
    entries = [
        "127.0.0.1   backoffice.coimbra.local",
        "127.0.0.1   bi.coimbra.local",
    ]

    evento_concluido.clear()
    spinner_thread = threading.Thread(target=mostrar_spinner, args=("A adicionar entradas ao ficheiro hosts...", evento_concluido))
    spinner_thread.start()

    try:
        added_entries = add_entries_to_hosts(entries, hosts_path)
        evento_concluido.set()
        spinner_thread.join()
        
        if added_entries:
            print(f"{Cores.VERDE_OK}Entradas adicionadas ao {hosts_path} com sucesso.{Cores.FIM}")
        else:
            print(f"{Cores.AVISO}Nenhuma alteração necessária. Todas as entradas já existiam no {hosts_path}.{Cores.FIM}")
    except PermissionError:
        evento_concluido.set()
        spinner_thread.join()
        print(f"{Cores.ERRO}Permissão negada: Execute este script como administrador ou com sudo.{Cores.FIM}")
    except Exception as e:
        evento_concluido.set()
        spinner_thread.join()
        print(f"{Cores.ERRO}Erro: {e}{Cores.FIM}")

if __name__ == "__main__":
    evento_concluido = threading.Event()
    main()
