# aiva/downscale_detection/pattern_engine.py

import logging
import time
from aiva.downscale_detection import config

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

class PatternEngine:
    def __init__(self, config_file=None):
        self.patterns = []
        if config_file:
            self.patterns = config.load_config(config_file)
        else:
            self.patterns = config.DEFAULT_DOWNSCALE_PATTERNS
        self.active_patterns = {}

    def process_event(self, event):
        logging.debug(f"Processing event: {event}")
        for pattern in self.patterns:
            self.evaluate_pattern(pattern, event)

    def evaluate_pattern(self, pattern, event):
        pattern_name = pattern['name']
        if pattern_name not in self.active_patterns:
            self.active_patterns[pattern_name] = {
                'start_time': time.time(),
                'events_received': []
            }

        active_pattern_data = self.active_patterns[pattern_name]
        active_pattern_data['events_received'].append(event)

        # Check if all required events have been received and conditions are met
        if self.pattern_matches(pattern, active_pattern_data['events_received']):
            logging.warning(f"Downscale pattern detected: {pattern_name}")
            logging.warning(f"Triggering events: {active_pattern_data['events_received']}")
            logging.warning(f"Consequence: {pattern['consequence']}")
            del self.active_patterns[pattern_name]
        else:
            # Check if the pattern has timed out
            elapsed_time = time.time() - active_pattern_data['start_time']
            max_window = max([e.get('window', 0) for e in pattern['events']])
            if elapsed_time > max_window:
                logging.debug(f"Pattern {pattern_name} timed out.")
                del self.active_patterns[pattern_name]


    def pattern_matches(self, pattern, received_events):
        # Simplifed matching logic.  A more robust implementation would track state
        # for each event in the pattern.
        for event_def in pattern['events']:
            found_match = False
            for received_event in received_events:
                if received_event['type'] == event_def['type']:
                    if 'threshold' in event_def and 'operator' in event_def:
                        if event_def['operator'] == '>=':
                            if received_event['value'] >= event_def['threshold']:
                                found_match = True
                                break
                        elif event_def['operator'] == '<=':
                            if received_event['value'] <= event_def['threshold']:
                                found_match = True
                                break
                        else:
                            logging.error(f"Unsupported operator: {event_def['operator']}")
                            return False
                    else:
                        found_match = True #No threshold or operator, assume match
                        break

            if event_def['required'] and not found_match:
                return False # Required event missing

        return True # All required events matched

if __name__ == '__main__':
    # Example usage
    engine = PatternEngine()

    # Simulate some events
    engine.process_event({'type': 'cpu_utilization', 'value': 95})
    engine.process_event({'type': 'memory_exhaustion'})

    engine.process_event({'type': 'latency', 'value': 600})
    engine.process_event({'type': 'error_rate', 'value': 7})

    engine.process_event({'type': 'cpu_utilization', 'value': 80})
    engine.process_event({'type': 'latency', 'value': 400})
