import os
import paramiko
from config import Config

def ensure_ssh_key():
    key_path = Config.DEFAULT_SSH_KEY_PATH
    pub_path = key_path + '.pub'
    
    if not os.path.exists(key_path):
        key = paramiko.RSAKey.generate(2048)
        key.write_private_key_file(key_path)
        
        pub_key = f"ssh-rsa {key.get_base64()} deployhub@dell-mini"
        with open(pub_path, 'w') as f:
            f.write(pub_key)
            
    with open(pub_path, 'r') as f:
        return f.read().strip()

def get_ssh_client(server):
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    
    key_path = getattr(server, 'ssh_key_path', None) or Config.DEFAULT_SSH_KEY_PATH
    auth_type = getattr(server, 'auth_type', 'key')
    password = getattr(server, 'password', None)
    
    # Try key first if specified
    if auth_type == 'key' and os.path.exists(key_path):
        try:
            client.connect(
                hostname=server.ip,
                port=server.ssh_port,
                username=server.ssh_user,
                key_filename=key_path,
                timeout=15
            )
            return client
        except Exception:
            client.close()
            client = paramiko.SSHClient()
            client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    
    # Fallback to password if key fails or password specified
    if password:
        try:
            client.connect(
                hostname=server.ip,
                port=server.ssh_port,
                username=server.ssh_user,
                password=password,
                timeout=15
            )
            return client
        except Exception as e:
            client.close()
            raise e
            
    raise ValueError("Falha ao autenticar via SSH (nem Chave SSH nem Senha funcionaram).")

def test_connection(server):
    try:
        client = get_ssh_client(server)
        stdin, stdout, stderr = client.exec_command("echo connection_ok", timeout=10)
        res = stdout.read().decode().strip()
        client.close()
        return res == "connection_ok"
    except Exception as e:
        return False

def execute_command(server, command, timeout=600):
    client = get_ssh_client(server)
    try:
        stdin, stdout, stderr = client.exec_command(command, timeout=timeout)
        exit_code = stdout.channel.recv_exit_status()
        out_str = stdout.read().decode('utf-8', errors='replace')
        err_str = stderr.read().decode('utf-8', errors='replace')
        client.close()
        return exit_code, out_str, err_str
    except Exception as e:
        client.close()
        raise e

def upload_file(server, local_path, remote_path):
    client = get_ssh_client(server)
    try:
        sftp = client.open_sftp()
        sftp.put(local_path, remote_path)
        sftp.close()
        client.close()
        return True
    except Exception as e:
        client.close()
        raise e

def download_file(server, remote_path, local_path):
    client = get_ssh_client(server)
    try:
        sftp = client.open_sftp()
        sftp.get(remote_path, local_path)
        sftp.close()
        client.close()
        return True
    except Exception as e:
        client.close()
        raise e
