import os
import json
import tarfile
import tempfile
from datetime import datetime
from modules.ssh_manager import execute_command, get_ssh_client

def list_remote_dir(server_data, base_app_path, subpath=""):
    """
    Lists files and directories inside the VPS app directory safely.
    Prevents directory traversal outside base_app_path.
    """
    class DummyServer:
        pass
    srv = DummyServer()
    srv.ip = server_data['ip']
    srv.ssh_port = server_data.get('ssh_port', 22)
    srv.ssh_user = server_data.get('ssh_user', 'root')
    srv.auth_type = server_data.get('auth_type', 'key')
    srv.ssh_key_path = server_data.get('ssh_key_path')
    srv.password = server_data.get('password')

    clean_sub = subpath.strip('/').replace('..', '')
    target_dir = os.path.normpath(os.path.join(base_app_path, clean_sub)).replace('\\', '/')

    script = f"""python3 - << 'EOF'
import os, sys, json, stat
from datetime import datetime

base_dir = "{target_dir}"
items = []

if os.path.exists(base_dir) and os.path.isdir(base_dir):
    try:
        for name in sorted(os.listdir(base_dir)):
            if name in ('.git', '__pycache__', '.pytest_cache'):
                continue
            full_p = os.path.join(base_dir, name)
            st = os.stat(full_p)
            is_dir = os.path.isdir(full_p)
            size_mb = round(st.st_size / (1024 * 1024), 3) if not is_dir else 0.0
            mtime = datetime.fromtimestamp(st.st_mtime).strftime('%d/%m/%Y %H:%M')
            mode_str = oct(stat.S_IMODE(st.st_mode))[2:]
            
            items.append({{
                'name': name,
                'is_dir': is_dir,
                'size_mb': size_mb,
                'mtime': mtime,
                'mode': mode_str,
                'rel_path': os.path.relpath(full_p, "{base_app_path}").replace('\\\\', '/')
            }})
    except Exception as e:
        pass

print(json.dumps({{
    'current_dir': "{target_dir}",
    'rel_dir': "{clean_sub}",
    'items': items
}}))
EOF
"""
    exit_code, out, _ = execute_command(srv, script)
    if exit_code == 0 and out.strip():
        try:
            return json.loads(out.strip())
        except Exception:
            pass
    return {'current_dir': target_dir, 'rel_dir': clean_sub, 'items': []}

def read_remote_file_content(server_data, base_app_path, rel_file_path):
    """
    Reads the content of a remote text file (up to 500 lines) safely.
    """
    class DummyServer:
        pass
    srv = DummyServer()
    srv.ip = server_data['ip']
    srv.ssh_port = server_data.get('ssh_port', 22)
    srv.ssh_user = server_data.get('ssh_user', 'root')
    srv.auth_type = server_data.get('auth_type', 'key')
    srv.ssh_key_path = server_data.get('ssh_key_path')
    srv.password = server_data.get('password')

    clean_file = rel_file_path.strip('/').replace('..', '')
    target_file = os.path.normpath(os.path.join(base_app_path, clean_file)).replace('\\', '/')

    script = f"""python3 - << 'EOF'
import os, json

file_p = "{target_file}"
content = ""
lines_count = 0

if os.path.exists(file_p) and os.path.isfile(file_p):
    try:
        with open(file_p, 'r', encoding='utf-8', errors='ignore') as f:
            lines = f.readlines()
            lines_count = len(lines)
            content = "".join(lines[:500])
    except Exception as e:
        content = f"Erro ao ler arquivo: {{str(e)}}"

print(json.dumps({{
    'file_path': "{target_file}",
    'rel_path': "{clean_file}",
    'lines_count': lines_count,
    'content': content
}}))
EOF
"""
    exit_code, out, _ = execute_command(srv, script)
    if exit_code == 0 and out.strip():
        try:
            return json.loads(out.strip())
        except Exception:
            pass
    return {'file_path': target_file, 'rel_path': clean_file, 'lines_count': 0, 'content': 'Erro ao ler arquivo.'}

def create_live_vps_snapshot(server_data, app_data):
    """
    Creates a live snapshot archive (.tar.gz) of the current VPS application directory.
    """
    class DummyServer:
        pass
    srv = DummyServer()
    srv.ip = server_data['ip']
    srv.ssh_port = server_data.get('ssh_port', 22)
    srv.ssh_user = server_data.get('ssh_user', 'root')
    srv.auth_type = server_data.get('auth_type', 'key')
    srv.ssh_key_path = server_data.get('ssh_key_path')
    srv.password = server_data.get('password')

    app_slug = app_data['name'].lower().replace(' ', '_').replace('-', '_')
    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
    remote_snapshot_dir = f"/var/backups/snapshots/{app_slug}"
    remote_snapshot_tar = f"{remote_snapshot_dir}/snapshot_{app_slug}_{timestamp}.tar.gz"
    target_path = app_data['path']

    cmd = f"""
    mkdir -p '{remote_snapshot_dir}'
    tar --exclude='venv' --exclude='node_modules' -czf '{remote_snapshot_tar}' -C '{target_path}' .
    du -m '{remote_snapshot_tar}' | cut -f1
    """
    exit_code, out, err = execute_command(srv, cmd)
    if exit_code == 0:
        try:
            size_mb = float(out.strip().splitlines()[-1])
        except Exception:
            size_mb = 1.0

        return {
            'file_name': f"snapshot_{app_slug}_{timestamp}.tar.gz",
            'remote_path': remote_snapshot_tar,
            'size_mb': round(size_mb, 1),
            'timestamp': datetime.now().strftime('%d/%m/%Y %H:%M:%S')
        }
    else:
        raise Exception(f"Falha ao gerar snapshot: {err}")
