#!/usr/bin/env python3
import os
import subprocess
import requests
import time
import json

TELEGRAM_TOKEN = "8816727123:AAFvd_1oh1ZAQq69kz1mvD1QCWbZyMkaRKw"
CHAT_ID = "1640434336"
PROXMOX_HOST = "100.92.204.81"
PROXMOX_USER = "root"

def run_ssh(cmd, timeout=10):
    """Esegue comando su Proxmox via SSH con chiave."""
    full = f"ssh -o ConnectTimeout={timeout} -o BatchMode=yes {PROXMOX_USER}@{PROXMOX_HOST} {cmd}"
    return subprocess.getoutput(full)

def run_ssh_json(cmd, timeout=10):
    """Esegue comando e prova a parsare JSON."""
    out = run_ssh(cmd, timeout)
    try:
        return json.loads(out)
    except json.JSONDecodeError:
        return None

def check_arm():
    """Check server Oracle ARM locale."""
    lines = []
    
    # Disco
    df = subprocess.getoutput("df -h / | tail -1 | awk '{print $5}'")
    lines.append(f"💾 Disco ARM: {df} occupato")
    
    # RAM
    ram = subprocess.getoutput("free -m | awk 'NR==2{printf \"%.1f%%\", $3*100/$2 }'")
    lines.append(f"🧠 RAM ARM: {ram} usata")
    
    # Hermes gateway (con retry + fallback cron)
    hermes_status = ""
    # In cron non c'è DBUS_SESSION_BUS_ADDRESS -> systemctl --user fallisce
    if os.environ.get("DBUS_SESSION_BUS_ADDRESS"):
        for _ in range(3):
            hermes_status = subprocess.getoutput("systemctl --user is-active hermes-gateway")
            if hermes_status == "active":
                break
            time.sleep(2)
    else:
        # Fallback: cerca il processo via pgrep
        hermes_status = "active" if subprocess.getoutput("pgrep -f 'hermes.*gateway'") else "inactive (cron)"
    
    status = "✅ ONLINE" if hermes_status == "active" else f"❌ OFFLINE ({hermes_status})"
    lines.append(f"🤖 Hermes Gateway: {status}")
    
    # Docker containers
    docker_ps = subprocess.getoutput("sudo docker ps --format '{{.Names}}: {{.Status}}' 2>/dev/null")
    if docker_ps:
        lines.append(f"🐳 Docker: {docker_ps.replace(chr(10), ', ')}")
    
    return lines

def check_proxmox():
    """Check completo Proxmox via SSH - supporta cluster multi-nodo."""
    lines = []
    
    # Get all nodes in cluster
    nodes_list = run_ssh_json("pvesh get /nodes --output-format=json")
    if not nodes_list:
        lines.append("🖥️  **Proxmox**: ❌ irraggiungibile")
        return lines
    
    # Cluster resources (all nodes)
    resources = run_ssh_json("pvesh get /cluster/resources --output-format=json")
    
    for node_info in nodes_list:
        node_name = node_info.get('node', 'unknown')
        cpu_pct = node_info.get('cpu', 0) * 100
        mem_pct = node_info.get('mem', 0) / node_info.get('maxmem', 1) * 100
        disk_pct = node_info.get('disk', 0) / node_info.get('maxdisk', 1) * 100
        up_days = node_info.get('uptime', 0) // 86400
        status = node_info.get('status', 'unknown')
        
        status_icon = "🟢" if status == "online" else "🔴"
        lines.append(f"🖥️  **{node_name}** {status_icon} — up {up_days}d | CPU {cpu_pct:.0f}% | RAM {mem_pct:.0f}% | Disco {disk_pct:.0f}%")
        
        # VMs/CTs for this node
        if resources:
            node_vms = [r for r in resources if r.get('node') == node_name and r.get('type') in ('qemu', 'lxc')]
            node_running = [v for v in node_vms if v.get('status') == 'running']
            node_stopped = [v for v in node_vms if v.get('status') != 'running']
            
            if node_vms:
                lines.append(f"📦 **VM/CT su {node_name}**: {len(node_running)}/{len(node_vms)} running")
                for v in node_running:
                    t = "VM" if v.get('type') == 'qemu' else "CT"
                    cpu = v.get('cpu', 0) * 100
                    mem_pct = v.get('mem', 0) / v.get('maxmem', 1) * 100
                    name = v.get('name', v.get('vmid'))
                    lines.append(f"   {t} {v['vmid']} ({name}): CPU {cpu:.0f}% RAM {mem_pct:.0f}%")
                if node_stopped:
                    for v in node_stopped:
                        lines.append(f"   ⏹️ {v['type'].upper()} {v['vmid']} ({v.get('name', '')}): {v.get('status')}")
    
    # Storage (deduplicato per cluster)
    storages = run_ssh_json("pvesh get /cluster/resources --type storage --output-format=json")
    if storages:
        lines.append("💿 **Storage**:")
        seen = set()
        for s in storages:
            key = (s.get('storage'), s.get('node'))
            if key in seen:
                continue
            seen.add(key)
            if s.get('maxdisk', 0) > 0:
                pct = s.get('disk', 0) / s['maxdisk'] * 100
                icon = "🔴" if pct > 85 else "🟡" if pct > 70 else "🟢"
                node_label = f" ({s.get('node')})" if len(nodes_list) > 1 else ""
                lines.append(f"   {icon} {s['storage']}{node_label}: {pct:.0f}% ({s.get('disk',0)//1024**3}GB/{s['maxdisk']//1024**3}GB)")
    
    # Backup jobs
    backups = run_ssh_json("pvesh get /cluster/backup --output-format=json")
    if backups:
        lines.append("💾 **Backup jobs**:")
        for b in backups:
            if b.get('enabled'):
                sched = b.get('schedule', '?')
                stor = b.get('storage', '?')
                excl = b.get('exclude', '')
                lines.append(f"   • {sched} → {stor} (esclude: {excl or 'nessuno'})")
    
    # Updates available
    updates = run_ssh("apt list --upgradable 2>/dev/null | grep -c upgradable")
    if updates and updates.strip().isdigit() and int(updates) > 0:
        lines.append(f"📦 **Aggiornamenti pendenti**: {updates.strip()}")
    
    return lines

def build_report():
    report = "🤖 *J.A.R.V.I.S. Morning Briefing*\n\n"
    
    # ARM Section
    report += "━━━ *Oracle ARM (Cloud)* ━━━\n"
    for line in check_arm():
        report += f"{line}\n"
    
    report += "\n━━━ *Proxmox (Home Lab)* ━━━\n"
    for line in check_proxmox():
        report += f"{line}\n"
    
    # Night report (placeholder)
    report += "\n🎯 *Report Notturno:*\n"
    report += "- Lavori Upwork: 0\n"
    report += "- Backup PBS: OK (ultimo run domenica)\n"
    report += "- Nessun alert critico\n"
    
    report += "\n_I server sono stabili. Pronti per un'altra giornata, Signore._"
    return report

def send_telegram(text):
    url = f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendMessage"
    payload = {"chat_id": CHAT_ID, "text": text, "parse_mode": "Markdown"}
    try:
        r = requests.post(url, json=payload, timeout=10)
        r.raise_for_status()
        print("[+] Morning Briefing inviato con successo a Telegram.")
    except Exception as e:
        print(f"[-] Errore invio Telegram: {e}")

if __name__ == "__main__":
    briefing = build_report()
    send_telegram(briefing)