"""
ErrorAnalyzer
Generated by Eden via recursive self-improvement
2025-10-27 21:21:21.551328
"""

class ErrorAnalyzer:
    """
    A class to analyze logs and identify root cause of errors.
    
    Attributes:
        logs (list): List to store log entries
        error_counts (dict): Dictionary to track frequency of each error message
        known_errors (dict): Dictionary mapping common error patterns to explanations
    """

    def __init__(self):
        self.logs = []
        self.error_counts = {}
        self.known_errors = {
            "connection refused": "Check if the service is running and network connectivity is good.",
            "timeout occurred": "Increase timeout limits or optimize database queries.",
            "out of memory": "Optimize memory usage or increase system resources.",
            "not found": "Verify paths and ensure resources are properly loaded."
        }

    def add_log(self, log_entry):
        """
        Add a new log entry to the analysis.
        
        Args:
            log_entry (str): The log message to analyze
        """
        self.logs.append(log_entry)
        error = self._extract_error(log_entry)
        if error:
            self.error_counts[error] = self.error_counts.get(error, 0) + 1

    def _extract_error(self, log_entry):
        """
        Extract the error message from a log entry.
        
        Args:
            log_entry (str): The log message to process
        Returns:
            str or None: The extracted error message if present
        """
        parts = log_entry.split()
        for part in parts:
            if part.endswith('error'):
                return part
        return None

    def find_top_errors(self, num=3):
        """
        Find the top N most frequent errors.
        
        Args:
            num (int): Number of errors to return
        Returns:
            list: List of tuples (error_message, count)
        """
        sorted_errors = sorted(
            self.error_counts.items(),
            key=lambda x: -x[1]
        )[:num]
        return sorted_errors

    def explain_error(self, error_message):
        """
        Provide explanation for an error message.
        
        Args:
            error_message (str): The error to explain
        Returns:
            str: Explanation based on known patterns
        """
        matches = []
        for pattern, explanation in self.known_errors.items():
            if pattern in error_message.lower():
                matches.append((pattern, explanation))
        if not matches:
            return f"No known explanation for: {error_message}"
        return "\n".join([
            f"Pattern: {p} \nExplanation: {e}" 
            for p, e in sorted(matches, key=lambda x: len(x[0]), reverse=True)
        ])

    def generate_explanation(self, error):
        """
        Helper function to format explanations.
        
        Args:
            error (str): The error message
        Returns:
            str: Formatted explanation string
        """
        explanation = self.explain_error(error)
        return f"Analysis:\n{explanation}"

# Example usage:
if __name__ == "__main__":
    analyzer = ErrorAnalyzer()
    
    # Sample logs
    logs = [
        "GET /api/data HTTP/1.1 404 Not Found",
        "Connection to database timed out",
        "User login failed: connection refused",
        "MemoryError: out of memory allocating 1M bytes",
        "API call timeout occurred on endpoint /metrics",
        "File not found: missing.txt"
    ]
    
    # Process logs
    for log in logs:
        analyzer.add_log(log)
    
    # Analyze results
    top_errors = analyzer.find_top_errors()
    print("Top Errors:")
    for error, count in top_errors:
        print(f"{error}: {count} occurrence{'s' if count > 1 else ''}")
    
    # Get explanations
    for log in logs:
        error = analyzer._extract_error(log)
        if error:
            explanation = analyzer.generate_explanation(error)
            print("\n", explanation, "\n")