"""
Large test file for context engine chunking test.
This file contains many lines to test the 8000 token limit per chunk.
"""

import logging
from typing import List, Dict, Any, Optional, Tuple
from dataclasses import dataclass
from pathlib import Path


logger = logging.getLogger(__name__)


@dataclass
class DataProcessor:
    """Process various types of data."""
    
    name: str
    version: str
    config: Dict[str, Any]
    cache: Dict[str, Any]
    
    def __post_init__(self):
        """Initialize processor."""
        if not self.cache:
            self.cache = {}
        logger.info(f"Initialized {self.name} v{self.version}")
    
    def process_data(self, data: List[Dict]) -> List[Dict]:
        """Process input data."""
        results = []
        for item in data:
            try:
                processed = self._process_item(item)
                results.append(processed)
            except Exception as e:
                logger.error(f"Error processing item: {e}")
                continue
        return results
    
    def _process_item(self, item: Dict) -> Dict:
        """Process single item."""
        result = {
            'id': item.get('id'),
            'processed': True,
            'data': self._transform_data(item.get('data', {})),
            'metadata': self._extract_metadata(item),
        }
        return result
    
    def _transform_data(self, data: Dict) -> Dict:
        """Transform data."""
        transformed = {}
        for key, value in data.items():
            if isinstance(value, str):
                transformed[key] = value.upper()
            elif isinstance(value, int):
                transformed[key] = value * 2
            elif isinstance(value, list):
                transformed[key] = [self._transform_item(v) for v in value]
            else:
                transformed[key] = value
        return transformed
    
    def _transform_item(self, item: Any) -> Any:
        """Transform individual item."""
        if isinstance(item, str):
            return item.lower()
        elif isinstance(item, dict):
            return self._transform_data(item)
        return item
    
    def _extract_metadata(self, item: Dict) -> Dict:
        """Extract metadata from item."""
        return {
            'created_at': item.get('created_at'),
            'updated_at': item.get('updated_at'),
            'author': item.get('author'),
            'tags': item.get('tags', []),
        }


class FileHandler:
    """Handle file operations."""
    
    def __init__(self, base_path: Path):
        self.base_path = base_path
        self.cache = {}
    
    def read_file(self, filename: str) -> Optional[str]:
        """Read file contents."""
        if filename in self.cache:
            return self.cache[filename]
        
        file_path = self.base_path / filename
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                content = f.read()
            self.cache[filename] = content
            return content
        except FileNotFoundError:
            logger.error(f"File not found: {filename}")
            return None
        except Exception as e:
            logger.error(f"Error reading file {filename}: {e}")
            return None
    
    def write_file(self, filename: str, content: str) -> bool:
        """Write content to file."""
        file_path = self.base_path / filename
        try:
            file_path.parent.mkdir(parents=True, exist_ok=True)
            with open(file_path, 'w', encoding='utf-8') as f:
                f.write(content)
            self.cache[filename] = content
            return True
        except Exception as e:
            logger.error(f"Error writing file {filename}: {e}")
            return False
    
    def list_files(self, pattern: str = "*") -> List[Path]:
        """List files matching pattern."""
        try:
            return list(self.base_path.glob(pattern))
        except Exception as e:
            logger.error(f"Error listing files: {e}")
            return []


class DataValidator:
    """Validate data structures."""
    
    def __init__(self, strict: bool = False):
        self.strict = strict
        self.errors = []
    
    def validate(self, data: Dict, schema: Dict) -> bool:
        """Validate data against schema."""
        self.errors = []
        return self._validate_dict(data, schema)
    
    def _validate_dict(self, data: Dict, schema: Dict) -> bool:
        """Validate dictionary."""
        for key, expected_type in schema.items():
            if key not in data:
                if self.strict:
                    self.errors.append(f"Missing required key: {key}")
                    return False
                continue
            
            if not isinstance(data[key], expected_type):
                self.errors.append(f"Invalid type for {key}: expected {expected_type}, got {type(data[key])}")
                if self.strict:
                    return False
        
        return len(self.errors) == 0
    
    def get_errors(self) -> List[str]:
        """Get validation errors."""
        return self.errors.copy()


class CacheManager:
    """Manage caching operations."""
    
    def __init__(self, max_size: int = 1000):
        self.max_size = max_size
        self.cache = {}
        self.access_count = {}
    
    def get(self, key: str) -> Optional[Any]:
        """Get value from cache."""
        if key in self.cache:
            self.access_count[key] = self.access_count.get(key, 0) + 1
            return self.cache[key]
        return None
    
    def set(self, key: str, value: Any) -> None:
        """Set value in cache."""
        if len(self.cache) >= self.max_size:
            self._evict()
        self.cache[key] = value
        self.access_count[key] = 1
    
    def _evict(self) -> None:
        """Evict least accessed item."""
        if not self.cache:
            return
        
        min_key = min(self.access_count, key=self.access_count.get)
        del self.cache[min_key]
        del self.access_count[min_key]
    
    def clear(self) -> None:
        """Clear cache."""
        self.cache.clear()
        self.access_count.clear()


class MetricsCollector:
    """Collect and analyze metrics."""
    
    def __init__(self):
        self.metrics = {}
        self.history = []
    
    def record(self, name: str, value: float) -> None:
        """Record a metric."""
        if name not in self.metrics:
            self.metrics[name] = []
        self.metrics[name].append(value)
        self.history.append((name, value))
    
    def get_average(self, name: str) -> Optional[float]:
        """Get average value for metric."""
        if name not in self.metrics or not self.metrics[name]:
            return None
        return sum(self.metrics[name]) / len(self.metrics[name])
    
    def get_max(self, name: str) -> Optional[float]:
        """Get maximum value for metric."""
        if name not in self.metrics or not self.metrics[name]:
            return None
        return max(self.metrics[name])
    
    def get_min(self, name: str) -> Optional[float]:
        """Get minimum value for metric."""
        if name not in self.metrics or not self.metrics[name]:
            return None
        return min(self.metrics[name])
    
    def get_summary(self) -> Dict[str, Dict[str, float]]:
        """Get summary of all metrics."""
        summary = {}
        for name in self.metrics:
            summary[name] = {
                'avg': self.get_average(name),
                'max': self.get_max(name),
                'min': self.get_min(name),
                'count': len(self.metrics[name]),
            }
        return summary


class ConfigManager:
    """Manage application configuration."""
    
    def __init__(self, config_file: Path):
        self.config_file = config_file
        self.config = {}
        self.load()
    
    def load(self) -> None:
        """Load configuration from file."""
        try:
            import json
            with open(self.config_file, 'r') as f:
                self.config = json.load(f)
            logger.info(f"Loaded config from {self.config_file}")
        except FileNotFoundError:
            logger.warning(f"Config file not found: {self.config_file}")
            self.config = self._get_defaults()
        except Exception as e:
            logger.error(f"Error loading config: {e}")
            self.config = self._get_defaults()
    
    def save(self) -> bool:
        """Save configuration to file."""
        try:
            import json
            with open(self.config_file, 'w') as f:
                json.dump(self.config, f, indent=2)
            logger.info(f"Saved config to {self.config_file}")
            return True
        except Exception as e:
            logger.error(f"Error saving config: {e}")
            return False
    
    def get(self, key: str, default: Any = None) -> Any:
        """Get configuration value."""
        return self.config.get(key, default)
    
    def set(self, key: str, value: Any) -> None:
        """Set configuration value."""
        self.config[key] = value
    
    def _get_defaults(self) -> Dict:
        """Get default configuration."""
        return {
            'version': '1.0.0',
            'debug': False,
            'log_level': 'INFO',
            'cache_size': 1000,
            'timeout': 30,
            'max_retries': 3,
        }


class TaskQueue:
    """Simple task queue implementation."""
    
    def __init__(self):
        self.queue = []
        self.completed = []
        self.failed = []
    
    def add_task(self, task: Dict) -> None:
        """Add task to queue."""
        self.queue.append(task)
    
    def get_next_task(self) -> Optional[Dict]:
        """Get next task from queue."""
        if not self.queue:
            return None
        return self.queue.pop(0)
    
    def mark_completed(self, task: Dict) -> None:
        """Mark task as completed."""
        self.completed.append(task)
    
    def mark_failed(self, task: Dict, error: str) -> None:
        """Mark task as failed."""
        task['error'] = error
        self.failed.append(task)
    
    def get_status(self) -> Dict:
        """Get queue status."""
        return {
            'pending': len(self.queue),
            'completed': len(self.completed),
            'failed': len(self.failed),
        }


class EventEmitter:
    """Simple event emitter."""
    
    def __init__(self):
        self.listeners = {}
    
    def on(self, event: str, callback) -> None:
        """Register event listener."""
        if event not in self.listeners:
            self.listeners[event] = []
        self.listeners[event].append(callback)
    
    def emit(self, event: str, *args, **kwargs) -> None:
        """Emit event."""
        if event in self.listeners:
            for callback in self.listeners[event]:
                try:
                    callback(*args, **kwargs)
                except Exception as e:
                    logger.error(f"Error in event listener for {event}: {e}")
    
    def off(self, event: str, callback) -> None:
        """Remove event listener."""
        if event in self.listeners:
            try:
                self.listeners[event].remove(callback)
            except ValueError:
                pass


class RateLimiter:
    """Rate limiter implementation."""
    
    def __init__(self, max_calls: int, time_window: int):
        self.max_calls = max_calls
        self.time_window = time_window
        self.calls = []
    
    def can_proceed(self) -> bool:
        """Check if call can proceed."""
        import time
        current_time = time.time()
        
        # Remove old calls
        self.calls = [t for t in self.calls if current_time - t < self.time_window]
        
        if len(self.calls) < self.max_calls:
            self.calls.append(current_time)
            return True
        return False
    
    def wait_time(self) -> float:
        """Get time to wait before next call."""
        if not self.calls:
            return 0
        
        import time
        current_time = time.time()
        oldest_call = min(self.calls)
        time_passed = current_time - oldest_call
        
        if time_passed >= self.time_window:
            return 0
        return self.time_window - time_passed


def process_batch(items: List[Any], batch_size: int = 100) -> List[List[Any]]:
    """Split items into batches."""
    batches = []
    for i in range(0, len(items), batch_size):
        batches.append(items[i:i + batch_size])
    return batches


def retry_with_backoff(func, max_retries: int = 3, base_delay: float = 1.0):
    """Retry function with exponential backoff."""
    import time
    
    for attempt in range(max_retries):
        try:
            return func()
        except Exception as e:
            if attempt == max_retries - 1:
                raise
            
            delay = base_delay * (2 ** attempt)
            logger.warning(f"Attempt {attempt + 1} failed: {e}. Retrying in {delay}s...")
            time.sleep(delay)


def safe_divide(a: float, b: float, default: float = 0.0) -> float:
    """Safely divide two numbers."""
    try:
        return a / b
    except ZeroDivisionError:
        return default


def merge_dicts(*dicts: Dict) -> Dict:
    """Merge multiple dictionaries."""
    result = {}
    for d in dicts:
        result.update(d)
    return result


def flatten_list(nested_list: List) -> List:
    """Flatten nested list."""
    result = []
    for item in nested_list:
        if isinstance(item, list):
            result.extend(flatten_list(item))
        else:
            result.append(item)
    return result
