#!/usr/bin/env python3
import os
import sys
import time
import json
import socket
import urllib.request
import urllib.error

# telemetry_agent.py - Hive Monero telemetry collector
# Reads config from config.json automatically

CONFIG_PATH = "/opt/monero-monitor/config.json"

def read_config():
    if not os.path.exists(CONFIG_PATH):
        print(f"Error: No se encuentra config.json en {CONFIG_PATH}")
        sys.exit(1)
    try:
        with open(CONFIG_PATH, "r") as f:
            return json.load(f)
    except Exception as e:
        print(f"Error leyendo config.json: {e}")
        sys.exit(1)

def get_cpu_temp():
    # Attempt to read Linux thermal zone temperature
    try:
        for tz in range(10):
            type_path = f"/sys/class/thermal/thermal_zone{tz}/type"
            temp_path = f"/sys/class/thermal/thermal_zone{tz}/temp"
            if os.path.exists(type_path) and os.path.exists(temp_path):
                with open(type_path, "r") as f:
                    tz_type = f.read().strip().lower()
                if "cpu" in tz_type or "x86_pkg" in tz_type:
                    with open(temp_path, "r") as f:
                        return float(f.read().strip()) / 1000.0
        # Fallback to first available zone
        if os.path.exists("/sys/class/thermal/thermal_zone0/temp"):
            with open("/sys/class/thermal/thermal_zone0/temp", "r") as f:
                return float(f.read().strip()) / 1000.0
    except Exception:
        pass
    
    # Fallback: try k10temp from hwmon (AMD CPU)
    try:
        for hw in range(10):
            name_path = f"/sys/class/hwmon/hwmon{hw}/name"
            if os.path.exists(name_path):
                with open(name_path, "r") as f:
                    name = f.read().strip().lower()
                if "k10temp" in name:
                    temp_path = f"/sys/class/hwmon/hwmon{hw}/temp1_input"
                    if os.path.exists(temp_path):
                        with open(temp_path, "r") as f:
                            return float(f.read().strip()) / 1000.0
    except Exception:
        pass
    
    return 42.0 # fallback default temp

def get_xmrig_stats():
    # Attempt to query local XMRig API on port 12222
    try:
        req = urllib.request.Request("http://localhost:12222/1/summary")
        with urllib.request.urlopen(req, timeout=2) as response:
            data = json.loads(response.read().decode())
            hashrate = data.get("hashrate", {}).get("total", [0])[0]
            # XMRig reports temp if supported, else query cpu
            temp = data.get("connection", {}).get("ping", 42.0) # ping or other fallback
            return float(hashrate), None
    except Exception:
        return None, None

def main():
    print("Iniciando Agente de Telemetría Monero...")
    config = read_config()
    server_url = config.get("server_url")
    worker_id = config.get("worker_id")
    worker_token = config.get("worker_token")

    while True:
        try:
            # Query hashrate
            hashrate, xmrig_temp = get_xmrig_stats()
            if hashrate is None:
                hashrate = 0.0 # XMRig offline or not reporting
            
            # Query temperature
            temp = xmrig_temp if xmrig_temp is not None else get_cpu_temp()

            # Prepare metrics payload
            payload = {
                "worker_id": worker_id,
                "hashrate": hashrate,
                "temperature": temp,
                "timestamp": int(time.time())
            }

            # POST request
            url = f"{server_url}/api/metrics"
            req = urllib.request.Request(
                url,
                data=json.dumps(payload).encode("utf-8"),
                headers={
                    "Content-Type": "application/json",
                    "X-Worker-Token": worker_token
                },
                method="POST"
            )

            with urllib.request.urlopen(req, timeout=5) as response:
                res_body = json.loads(response.read().decode())
                print(f"Métricas enviadas correctamente. Estado: {res_body.get('status')}")

        except urllib.error.URLError as e:
            print(f"Error de conexión con el servidor: {e}")
        except Exception as e:
            print(f"Error inesperado en agente: {e}")

        time.sleep(10) # Send metrics every 10 seconds

if __name__ == "__main__":
    main()
