"""
PCAP file loading utilities
"""

import sys
from typing import List, Iterator, Optional

try:
    from scapy.all import rdpcap, PcapReader, Packet
except ImportError:
    print("Error: scapy library required. Install with: pip install scapy")
    sys.exit(1)


class PCAPLoader:
    """Utility class for loading PCAP files"""
    
    def __init__(self, file_path: str):
        self.file_path = file_path
        self._packet_count: Optional[int] = None
    
    def load_all(self) -> List[Packet]:
        """Load all packets from the PCAP file with memory management"""
        try:
            # Check file size and warn for large files
            import os
            file_size = os.path.getsize(self.file_path)
            if file_size > 100 * 1024 * 1024:  # > 100MB
                print(f"Warning: Large PCAP file ({file_size / (1024*1024):.1f} MB)")
                print("Consider using streaming mode for better memory management")
                
            # Force garbage collection before loading
            import gc
            gc.collect()
            
            packets = rdpcap(self.file_path)
            self._packet_count = len(packets)
            
            print(f"Loaded {len(packets)} packets ({file_size / (1024*1024):.1f} MB)")
            return packets
            
        except MemoryError:
            raise IOError(f"Out of memory loading PCAP file {self.file_path}. Try using streaming mode.")
        except Exception as e:
            raise IOError(f"Error loading PCAP file {self.file_path}: {e}")
    
    def load_streaming(self, chunk_size: int = 1000) -> Iterator[List[Packet]]:
        """Load packets in chunks for memory efficiency"""
        try:
            with PcapReader(self.file_path) as pcap_reader:
                chunk = []
                for packet in pcap_reader:
                    chunk.append(packet)
                    if len(chunk) >= chunk_size:
                        yield chunk
                        chunk = []
                
                # Yield remaining packets
                if chunk:
                    yield chunk
                    
        except Exception as e:
            raise IOError(f"Error streaming PCAP file {self.file_path}: {e}")
    
    def get_packet_count(self) -> Optional[int]:
        """Get the total number of packets (if loaded)"""
        return self._packet_count
    
    def validate_file(self) -> bool:
        """Validate that the file exists and is a valid PCAP"""
        try:
            with PcapReader(self.file_path) as pcap_reader:
                # Try to read first packet
                next(iter(pcap_reader))
                return True
        except (IOError, StopIteration):
            return False
        except Exception:
            return False
    
    @staticmethod
    def get_file_info(file_path: str) -> dict:
        """Get basic information about a PCAP file"""
        try:
            packet_count = 0
            first_timestamp = None
            last_timestamp = None
            total_bytes = 0
            
            with PcapReader(file_path) as pcap_reader:
                for packet in pcap_reader:
                    packet_count += 1
                    total_bytes += len(packet)
                    
                    if first_timestamp is None:
                        first_timestamp = float(packet.time)
                    last_timestamp = float(packet.time)
            
            duration = (last_timestamp - first_timestamp) if first_timestamp and last_timestamp else 0
            
            return {
                'file_path': file_path,
                'packet_count': packet_count,
                'total_bytes': total_bytes,
                'duration_seconds': duration,
                'first_timestamp': first_timestamp,
                'last_timestamp': last_timestamp,
                'avg_packet_rate': packet_count / duration if duration > 0 else 0
            }
            
        except Exception as e:
            return {'error': str(e)}