import psutil
import platform
import time
import requests
import socket
import wmi
from datetime import datetime

# ===============================
# CONFIG
# ===============================
SERVER_URL = "https://app.technicalsams.my.id//api/monitoring/receive"
API_KEY = "e2b7c805bc20cc2aa418763887ef1e20"
INTERVAL = 60

# ===============================
# BASIC INFO
# ===============================
def get_basic_info():
    return {
        "hostname": socket.gethostname(),
        "ip": socket.gethostbyname(socket.gethostname()),
        "os": f"{platform.system()} {platform.release()}",
        "time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    }

# ===============================
# CPU
# ===============================
def get_cpu_info():
    return {
        "usage_percent": psutil.cpu_percent(interval=1),
        "core_count": psutil.cpu_count(logical=True)
    }

# ===============================
# RAM
# ===============================
def get_ram_info():
    mem = psutil.virtual_memory()
    return {
        "total_gb": round(mem.total / (1024 ** 3), 2),
        "used_gb": round(mem.used / (1024 ** 3), 2),
        "percent": mem.percent
    }

# ===============================
# DISK
# ===============================
def get_disk_info():
    disks = []
    for part in psutil.disk_partitions():
        try:
            usage = psutil.disk_usage(part.mountpoint)
            disks.append({
                "device": part.device,
                "mount": part.mountpoint,
                "total_gb": round(usage.total / (1024 ** 3), 2),
                "used_gb": round(usage.used / (1024 ** 3), 2),
                "percent": usage.percent
            })
        except:
            pass
    return disks

# ===============================
# SENSOR VIA LibreHardwareMonitor
# ===============================
def get_hardware_sensors():
    sensors = {
        "cpu_temp": [],
        "gpu_temp": [],
        "fan": []
    }

    try:
        # 🔥 GANTI NAMESPACE
        w = wmi.WMI(namespace="root\\LibreHardwareMonitor")

        for sensor in w.Sensor():
            if sensor.SensorType == "Temperature":
                if "CPU" in sensor.Name:
                    sensors["cpu_temp"].append({
                        "name": sensor.Name,
                        "value": round(sensor.Value, 2)
                    })

                elif "GPU" in sensor.Name:
                    sensors["gpu_temp"].append({
                        "name": sensor.Name,
                        "value": round(sensor.Value, 2)
                    })

            elif sensor.SensorType == "Fan":
                sensors["fan"].append({
                    "name": sensor.Name,
                    "rpm": int(sensor.Value)
                })

    except Exception as e:
        sensors["error"] = str(e)

    return sensors

# ===============================
# ERROR DETECTION
# ===============================
def get_errors():
    errors = []

    if psutil.virtual_memory().percent > 90:
        errors.append("RAM usage > 90%")

    if psutil.cpu_percent(interval=1) > 90:
        errors.append("CPU usage > 90%")

    return errors

# ===============================
# SEND DATA
# ===============================
def send_to_server(data):
    try:
        r = requests.post(
            SERVER_URL,
            json=data,
            headers={
                "Authorization": f"Bearer {API_KEY}",
                "Content-Type": "application/json"
            },
            timeout=10
        )

        print("STATUS:", r.status_code)
        print("RESPONSE:", r.text)

    except Exception as e:
        print("SEND ERROR:", e)

# ===============================
# MAIN LOOP
# ===============================
if __name__ == "__main__":
    print("Monitoring started with LibreHardwareMonitor...")
    while True:
        payload = {
            "basic": get_basic_info(),
            "cpu": get_cpu_info(),
            "ram": get_ram_info(),
            "disk": get_disk_info(),
            "sensors": get_hardware_sensors(),
            "errors": get_errors()
        }

        print(payload)
        send_to_server(payload)
        time.sleep(INTERVAL)
