import subprocess
import os
from typing import Dict, List
from loguru import logger
import json
import glob

class SystemChecker:
    @staticmethod
    def check_gpu_info() -> Dict:
        try:
            result = subprocess.run(['nvidia-smi', '--query-gpu=name,temperature.gpu,memory.used,memory.total,utilization.gpu,power.draw,power.limit', '--format=csv,noheader,nounits'], 
                                 capture_output=True, text=True)
            if result.returncode == 0:
                gpu_info = result.stdout.strip().split(',')
                return {
                    'name': gpu_info[0].strip(),
                    'temperature': float(gpu_info[1]),
                    'memory_used': float(gpu_info[2]),
                    'memory_total': float(gpu_info[3]),
                    'utilization': float(gpu_info[4]),
                    'power_draw': float(gpu_info[5]),
                    'power_limit': float(gpu_info[6])
                }
            return {}
        except Exception as e:
            logger.error(f"GPU 정보 확인 중 오류 발생: {str(e)}")
            return {}

    @staticmethod
    def check_cooling_system() -> Dict:
        cooling_info = {}
        try:
            # sensors 명령어로 전체 센서 정보 수집
            try:
                result = subprocess.run(['sensors', '-j'], capture_output=True, text=True)
                sensors_data = json.loads(result.stdout)
                cooling_info['sensors_data'] = sensors_data
            except Exception as e:
                logger.warning(f"sensors 명령어 실행 실패: {str(e)}")

            # hwmon 디렉토리에서 센서 정보 수집
            if os.path.exists('/sys/class/hwmon'):
                for hwmon in os.listdir('/sys/class/hwmon'):
                    hwmon_path = f'/sys/class/hwmon/{hwmon}'
                    if os.path.exists(f'{hwmon_path}/name'):
                        with open(f'{hwmon_path}/name', 'r') as f:
                            name = f.read().strip()
                            
                        # 수냉식 시스템 관련 센서 확인
                        if any(keyword in name.lower() for keyword in ['water', 'cooling', 'liquid', 'aio', 'pump']):
                            cooling_info['type'] = 'water'
                            cooling_info['sensor_name'] = name
                            
                            # 온도 센서 정보 수집
                            temp_inputs = glob.glob(f'{hwmon_path}/temp*_input')
                            for temp_input in temp_inputs:
                                try:
                                    with open(temp_input, 'r') as f:
                                        temp = float(f.read().strip()) / 1000.0
                                        label = os.path.basename(temp_input).replace('_input', '')
                                        cooling_info[f'temperature_{label}'] = temp
                                except Exception as e:
                                    logger.warning(f"온도 센서 읽기 실패 ({temp_input}): {str(e)}")
                            
                            # 팬 정보 수집
                            fan_inputs = glob.glob(f'{hwmon_path}/fan*_input')
                            for fan_input in fan_inputs:
                                try:
                                    with open(fan_input, 'r') as f:
                                        rpm = float(f.read().strip())
                                        label = os.path.basename(fan_input).replace('_input', '')
                                        cooling_info[f'fan_rpm_{label}'] = rpm
                                except Exception as e:
                                    logger.warning(f"팬 속도 읽기 실패 ({fan_input}): {str(e)}")
                            
                            # PWM 정보 수집
                            pwm_inputs = glob.glob(f'{hwmon_path}/pwm*')
                            for pwm_input in pwm_inputs:
                                try:
                                    with open(pwm_input, 'r') as f:
                                        pwm = float(f.read().strip())
                                        label = os.path.basename(pwm_input)
                                        cooling_info[f'pwm_{label}'] = pwm
                                except Exception as e:
                                    logger.warning(f"PWM 읽기 실패 ({pwm_input}): {str(e)}")

            # USB 장치 정보 수집
            try:
                result = subprocess.run(['lsusb'], capture_output=True, text=True)
                cooling_info['usb_devices'] = result.stdout
            except Exception as e:
                logger.warning(f"USB 장치 정보 수집 실패: {str(e)}")

            # I2C 장치 정보 수집
            try:
                result = subprocess.run(['i2cdetect', '-l'], capture_output=True, text=True)
                cooling_info['i2c_devices'] = result.stdout
            except Exception as e:
                logger.warning(f"I2C 장치 정보 수집 실패: {str(e)}")

            return cooling_info
        except Exception as e:
            logger.error(f"냉각 시스템 확인 중 오류 발생: {str(e)}")
            return {}

    @staticmethod
    def get_system_info() -> Dict:
        return {
            'gpu': SystemChecker.check_gpu_info(),
            'cooling': SystemChecker.check_cooling_system()
        } 