"""Core resource monitoring functionality."""

import os
import psutil
from typing import List, Optional
from srm.models import CPUMetrics, MemoryMetrics, DiskMetrics, DiskMetric, NetworkMetrics, ProcessInfo, AllMetrics


class ResourceMonitor:
    """Simple Resource Monitor for system metrics."""
    
    def __init__(self, config: Optional[dict] = None):
        self.config = config or {}
    
    def cpu_usage(self, interval: float = 0.1) -> CPUMetrics:
        percent = psutil.cpu_percent(interval=interval)
        per_core = psutil.cpu_percent(interval=interval, percpu=True)
        count = psutil.cpu_count() or 0
        try:
            load_avg = list(os.getloadavg())
        except AttributeError:
            load_avg = [0.0, 0.0, 0.0]
        return CPUMetrics(percent=percent or 0, per_core=per_core or [], count=count, load_avg=load_avg)
    
    def memory_info(self) -> MemoryMetrics:
        mem = psutil.virtual_memory()
        swap = psutil.swap_memory()
        return MemoryMetrics(
            total=mem.total, available=mem.available, used=mem.used, percent=mem.percent,
            swap_total=swap.total, swap_used=swap.used, swap_percent=swap.percent
        )
    
    def disk_usage(self) -> DiskMetrics:
        partitions = []
        for p in psutil.disk_partitions():
            if p.mountpoint.startswith(('/snap', '/dev', '/proc', '/sys', '/run')):
                continue
            try:
                usage = psutil.disk_usage(p.mountpoint)
                partitions.append(DiskMetric(
                    path=p.mountpoint, total=usage.total, used=usage.used,
                    free=usage.free, percent=usage.percent, mountpoint=p.mountpoint
                ))
            except (PermissionError, OSError):
                continue
        return DiskMetrics(partitions=partitions)
    
    def network_info(self) -> NetworkMetrics:
        net = psutil.net_io_counters()
        try:
            connections = len(psutil.net_connections(kind='inet'))
        except (PermissionError, psutil.AccessDenied):
            connections = 0
        return NetworkMetrics(
            bytes_sent=net.bytes_sent if net else 0,
            bytes_recv=net.bytes_recv if net else 0,
            connections=connections
        )
    
    def top_processes(self, count: int = 5) -> List[ProcessInfo]:
        processes = []
        for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']):
            try:
                info = proc.info
                processes.append(ProcessInfo(
                    pid=info['pid'], name=info['name'] or 'unknown',
                    cpu_percent=info.get('cpu_percent') or 0.0,
                    memory_percent=info.get('memory_percent') or 0.0
                ))
            except (psutil.NoSuchProcess, psutil.AccessDenied):
                continue
        processes.sort(key=lambda p: p.cpu_percent, reverse=True)
        return processes[:count]
    
    def all_metrics(self, process_count: int = 5) -> AllMetrics:
        return AllMetrics(
            cpu=self.cpu_usage(), memory=self.memory_info(),
            disk=self.disk_usage(), network=self.network_info(),
            top_processes=self.top_processes(count=process_count)
        )
