#!/usr/bin/env python3
import sys
import json
import re
import pty
import os
import subprocess
import errno

def get_sensors_data():
    try:
        raw_data = subprocess.check_output(["sensors"], text=True) #[cite: 1]
    except FileNotFoundError:
        return {"sensors_error": "Befehl 'sensors' nicht gefunden."} #[cite: 1]

    devices = {}
    blocks = raw_data.strip().split("\n\n") #[cite: 1]
    value_pattern = re.compile(r"[-+]?(\d+(?:\.\d+)?)") #[cite: 1]

    for block in blocks:
        lines = [l.strip() for l in block.split("\n") if l.strip()] #[cite: 1]
        if not lines:
            continue

        hardware_name = lines[0] #[cite: 1]
        readings = {}

        for line in lines[1:]:
            if line.startswith("Adapter:") or line.startswith("("): #[cite: 1]
                continue

            if ":" in line:
                sensor, val = line.split(":", 1) #[cite: 1]
                sensor = sensor.strip()
                val = val.strip()

                match = value_pattern.search(val) #[cite: 1]
                if match:
                    numeric_str = match.group(1)
                    if "." in numeric_str:
                        final_val = float(numeric_str)
                    else:
                        final_val = int(numeric_str)
                else:
                    final_val = val

                readings[sensor] = final_val

        if readings:
            devices[hardware_name] = readings #[cite: 1]

    try:
        gpu_temp_raw = subprocess.check_output(
            ["nvidia-smi", "--query-gpu=temperature.gpu", "--format=csv,noheader"],
            text=True
        ).strip() #[cite: 1]

        if gpu_temp_raw:
            devices["nvidia_gpu"] = {
                "GPUTemperature": int(gpu_temp_raw)
            } #[cite: 1]
    except (FileNotFoundError, subprocess.CalledProcessError):
        pass #[cite: 1]

    return devices

def get_ucc_status():
    master_fd, slave_fd = pty.openpty() #[cite: 2]

    try:
        proc = subprocess.Popen(
            ['ucc-cli', 'status'],
            stdout=slave_fd,
            stderr=slave_fd,
            close_fds=True
        ) #[cite: 2]
    except FileNotFoundError:
        return {"ucc_error": "ucc-cli nicht gefunden"} #[cite: 2]

    os.close(slave_fd) #[cite: 2]

    data = {}
    current_cat = None

    try:
        with os.fdopen(master_fd, 'r', encoding='utf-8', errors='ignore') as f:
            while True:
                try:
                    raw_line = f.readline() #[cite: 2]
                    if not raw_line:
                        break
                except OSError as e:
                    if e.errno == errno.EIO:
                        break
                    raise

                clean_line = re.sub(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])', '', raw_line) #[cite: 2]
                line = clean_line.replace('\xa0', ' ').strip() #[cite: 2]

                if not line:
                    continue

                cat_match = re.match(r"^---\s+(.*?)\s+---$", line) #[cite: 2]
                if cat_match:
                    current_cat = cat_match.group(1).lower().replace(" ", "_") #[cite: 2]
                    data[current_cat] = {}
                    continue

                if "===" in line: #[cite: 2]
                    continue

                if ":" in line and current_cat:
                    parts = line.split(":", 1) #[cite: 2]
                    key = parts[0].strip().lower().replace(" ", "_").replace("(", "").replace(")", "")
                    val = parts[1].strip()

                    if val.lower() == "yes":
                        val = True
                    elif val.lower() == "no":
                        val = False
                    else:
                        num_match = re.match(r"^([0-9.,]+)", val) #[cite: 2]
                        if num_match:
                            num_str = num_match.group(1).replace(",", ".")
                            try:
                                val = float(num_str) if "." in num_str else int(num_str)
                            except ValueError:
                                pass

                    data[current_cat][key] = val #[cite: 2]
    except Exception:
        pass

    proc.wait() #[cite: 2]
    return data

if __name__ == "__main__":
    # Führt beide Ergebnisse in einem gemeinsamen, flachen JSON-Objekt zusammen
    combined_result = {}
    combined_result.update(get_sensors_data()) #[cite: 1]
    combined_result.update(get_ucc_status()) #[cite: 2]
    print(json.dumps(combined_result, indent=2, ensure_ascii=False))
