from core.explanations.analyzers.BaseExplanationAnalyzer import BaseExplanationAnalyzer

import numpy as np


class InflatedExplanationAnalyzer(BaseExplanationAnalyzer):
    tolerance = 1e-9

    @staticmethod
    def calc_explanation_coverage(explanation, samples):
        if len(samples) == 0:
            return 0

        # Convert to numpy arrays for vectorized operations
        samples_array = np.array([sample.reshape(-1) for sample in samples])  # shape: (n_samples, n_features)
        bounds_array = np.array(explanation)  # shape: (n_features, 2)

        # Vectorized bounds checking with epsilon tolerance
        lower_bounds = bounds_array[:, 0] - InflatedExplanationAnalyzer.tolerance
        upper_bounds = bounds_array[:, 1] + InflatedExplanationAnalyzer.tolerance

        # Check if each feature of each sample is within bounds
        within_bounds = (samples_array >= lower_bounds) & (samples_array <= upper_bounds)

        # Count features within bounds for each sample and normalize
        feature_probs = np.mean(within_bounds, axis=1)  # Mean across features for each sample

        # Average across all samples
        coverage = np.mean(feature_probs)

        return coverage
