import nmap
import json
from pathlib import Path
from typing import List, Dict
from ..utils.logger import logger

class NetworkScanner:
    def __init__(self, cache_path: str = "switch_devices.json"):
        self.cache_path = Path(cache_path)
        self.nm = nmap.PortScanner()

    def scan_subnet(self, subnet: str = "192.168.1.0/24", ports: List[int] = [22, 23, 80]) -> List[Dict]:
        """扫描指定子网的设备，获取设备信息和开放端口"""
        logger.info(f"Scanning subnet: {subnet}")

        devices = []
        try:
            self.nm.scan(hosts=subnet, arguments=f'-p {",".join(map(str, ports))}')
            for host in self.nm.all_hosts():
                ip = host
                mac = self.nm[host]['addresses'].get('mac', 'N/A')
                open_ports = []

                if 'tcp' in self.nm[host]:
                    for port in self.nm[host]['tcp']:
                        if self.nm[host]['tcp'][port]['state'] == 'open':
                            open_ports.append(port)

                if open_ports:
                    devices.append({"ip": ip, "mac": mac, "ports": open_ports})
                    logger.debug(f"Found device: {ip} with open ports: {open_ports}")

        except Exception as e:
            logger.error(f"Error while scanning subnet: {e}")

        self._save_to_cache(devices)
        return devices

    def _save_to_cache(self, devices: List[Dict]):
        """保存扫描结果到本地文件"""
        with open(self.cache_path, "w") as f:
            json.dump(devices, f, indent=2)
        logger.info(f"Saved {len(devices)} devices to cache")

    def load_cached_devices(self) -> List[Dict]:
        """从缓存加载设备列表"""
        if not self.cache_path.exists():
            return []

        with open(self.cache_path) as f:
            return json.load(f)