import httpx
from typing import List, Optional, Dict
from app.config import settings
import json

class ProxmoxService:
    """Proxmox VE API 통신 서비스"""
    
    def __init__(self):
        self.base_url = settings.PROXMOX_HOST
        self.api_token = settings.PROXMOX_API_TOKEN
        self.verify_ssl = settings.PROXMOX_VERIFY_SSL
        
    async def _make_request(self, method: str, endpoint: str, **kwargs) -> Dict:
        """Proxmox API 요청"""
        url = f"{self.base_url}/api2/json{endpoint}"
        headers = {"Authorization": self.api_token}
        
        async with httpx.AsyncClient(verify=self.verify_ssl, timeout=30.0) as client:
            response = await client.request(method, url, headers=headers, **kwargs)
            response.raise_for_status()
            return response.json()
    
    async def get_nodes(self) -> List[Dict]:
        """노드 목록 조회"""
        result = await self._make_request("GET", "/nodes")
        return result.get("data", [])
    
    async def get_vms(self, node: str) -> List[Dict]:
        """특정 노드의 VM 목록 조회"""
        result = await self._make_request("GET", f"/nodes/{node}/qemu")
        return result.get("data", [])
    
    async def get_all_vms(self) -> List[Dict]:
        """모든 노드의 VM 목록 조회"""
        nodes = await self.get_nodes()
        print(f"DEBUG: 노드 목록: {nodes}")
        
        all_vms = []
        
        for node in nodes:
            node_name = node.get("node")
            if node_name:
                vms = await self.get_vms(node_name)
                print(f"DEBUG: {node_name} 노드의 VM 목록: {vms}")
                for vm in vms:
                    vm["node"] = node_name
                    all_vms.append(vm)
        
        print(f"DEBUG: 전체 VM 개수: {len(all_vms)}")
        print(f"DEBUG: 전체 VM 목록: {all_vms}")
        return all_vms
    
    async def get_vm_status(self, node: str, vm_id: int) -> Dict:
        """VM 상태 조회"""
        result = await self._make_request("GET", f"/nodes/{node}/qemu/{vm_id}/status/current")
        return result.get("data", {})
    
    async def get_vm_ip(self, node: str, vm_id: int) -> Optional[str]:
        """QEMU Guest Agent를 통해 VM IP 주소 조회"""
        try:
            result = await self._make_request(
                "GET", 
                f"/nodes/{node}/qemu/{vm_id}/agent/network-get-interfaces"
            )
            
            interfaces = result.get("data", {}).get("result", [])
            
            for iface in interfaces:
                # loopback 제외
                if "loopback" in iface.get("name", "").lower():
                    continue
                
                ip_addresses = iface.get("ip-addresses", [])
                for ip in ip_addresses:
                    if ip.get("ip-address-type") == "ipv4":
                        address = ip.get("ip-address")
                        # 사설 IP만 반환
                        if self._is_private_ip(address):
                            return address
            
            return None
        except:
            return None
    
    async def start_vm(self, node: str, vm_id: int) -> bool:
        """VM 시작"""
        try:
            await self._make_request("POST", f"/nodes/{node}/qemu/{vm_id}/status/start")
            return True
        except:
            return False
    
    async def stop_vm(self, node: str, vm_id: int) -> bool:
        """VM 종료"""
        try:
            await self._make_request("POST", f"/nodes/{node}/qemu/{vm_id}/status/stop")
            return True
        except:
            return False
    
    async def reboot_vm(self, node: str, vm_id: int) -> bool:
        """VM 재시작"""
        try:
            await self._make_request("POST", f"/nodes/{node}/qemu/{vm_id}/status/reboot")
            return True
        except:
            return False
    
    def _is_private_ip(self, ip: str) -> bool:
        """사설 IP 주소 확인"""
        if not ip:
            return False
        
        parts = ip.split(".")
        if len(parts) != 4:
            return False
        
        try:
            first = int(parts[0])
            second = int(parts[1])
            
            # 10.0.0.0/8
            if first == 10:
                return True
            
            # 172.16.0.0/12
            if first == 172 and 16 <= second <= 31:
                return True
            
            # 192.168.0.0/16
            if first == 192 and second == 168:
                return True
            
            return False
        except:
            return False

# 싱글톤 인스턴스
proxmox_service = ProxmoxService()
