"""
IP list file reader utility
"""

import os
import logging
from typing import Set, List
import ipaddress

class IPListReader:
    """Utility class for reading IP lists from files"""
    
    def __init__(self, ip_lists_dir: str = "ip_lists"):
        self.ip_lists_dir = ip_lists_dir
        self.logger = logging.getLogger("ip_reader")
        
        # Create directory if it doesn't exist
        os.makedirs(ip_lists_dir, exist_ok=True)
    
    def read_ip_list(self, provider: str) -> Set[str]:
        """Read IP list for a specific CDN provider"""
        filename = f"{provider}.txt"
        filepath = os.path.join(self.ip_lists_dir, filename)
        
        if not os.path.exists(filepath):
            self.logger.warning(f"IP list file not found: {filepath}")
            return set()
        
        ips = set()
        
        try:
            with open(filepath, 'r', encoding='utf-8') as f:
                for line_num, line in enumerate(f, 1):
                    line = line.strip()
                    
                    # Skip empty lines and comments
                    if not line or line.startswith('#'):
                        continue
                    
                    # Handle CIDR notation
                    if '/' in line:
                        try:
                            network = ipaddress.ip_network(line, strict=False)
                            
                            # Different sampling strategy for IPv4 vs IPv6
                            if network.version == 6:  # IPv6
                                # For IPv6, sample only first 32 IPs
                                self.logger.info(f"IPv6 network {line} - sampling first 32 IPs")
                                count = 0
                                for ip in network.hosts():
                                    if count >= 32:
                                        break
                                    ips.add(str(ip))
                                    count += 1
                            else:  # IPv4
                                # For IPv4, include all IPs
                                if network.num_addresses > 65536:  # /16 or larger
                                    self.logger.warning(f"Very large IPv4 network {line} with {network.num_addresses} IPs - this may take time")
                                
                                for ip in network.hosts():
                                    ips.add(str(ip))
                                    
                        except ValueError as e:
                            self.logger.warning(f"Invalid CIDR at line {line_num}: {line} - {e}")
                    else:
                        # Single IP address
                        try:
                            ip = ipaddress.ip_address(line)
                            ips.add(str(ip))
                        except ValueError as e:
                            self.logger.warning(f"Invalid IP at line {line_num}: {line} - {e}")
        
        except Exception as e:
            self.logger.error(f"Error reading IP list file {filepath}: {e}")
            return set()
        
        self.logger.info(f"Loaded {len(ips)} IPs for {provider} from {filepath}")
        return ips
    
    def read_all_ip_lists(self, providers: List[str]) -> dict:
        """Read IP lists for multiple providers"""
        all_ips = {}
        
        for provider in providers:
            ips = self.read_ip_list(provider)
            if ips:
                all_ips[provider] = ips
            else:
                self.logger.warning(f"No IPs loaded for provider: {provider}")
        
        total_ips = sum(len(ips) for ips in all_ips.values())
        self.logger.info(f"Loaded total of {total_ips} IPs across {len(all_ips)} providers")
        
        return all_ips
    
    def get_expected_files(self, providers: List[str]) -> List[str]:
        """Get list of expected IP list files"""
        return [os.path.join(self.ip_lists_dir, f"{provider}.txt") for provider in providers]
    
    def validate_ip_lists(self, providers: List[str]) -> dict:
        """Validate that IP list files exist and are readable"""
        validation_results = {}
        
        for provider in providers:
            filename = f"{provider}.txt"
            filepath = os.path.join(self.ip_lists_dir, filename)
            
            result = {
                'exists': os.path.exists(filepath),
                'readable': False,
                'ip_count': 0,
                'errors': []
            }
            
            if result['exists']:
                try:
                    with open(filepath, 'r', encoding='utf-8') as f:
                        result['readable'] = True
                        
                        # Quick count of valid IPs
                        for line in f:
                            line = line.strip()
                            if line and not line.startswith('#'):
                                try:
                                    if '/' in line:
                                        network = ipaddress.ip_network(line, strict=False)
                                        result['ip_count'] += min(network.num_addresses, 5000)
                                    else:
                                        ipaddress.ip_address(line)
                                        result['ip_count'] += 1
                                except ValueError:
                                    pass  # Skip invalid entries for quick validation
                                    
                except Exception as e:
                    result['errors'].append(str(e))
            
            validation_results[provider] = result
        
        return validation_results