"""
Test automatic intensity calculation for variance-aware anomaly visibility.

Verifies that auto-calculated intensities achieve 4x separation targets.
"""

import pytest
from datetime import datetime, timedelta
import polars as pl

from src.generate.processing.intensity_calculator import (
    calculate_anomaly_intensity, 
    validate_intensity_effectiveness
)
from src.generate.processing.anomalies import apply_daily_spike


def create_test_dataframe(start_date: datetime, end_date: datetime, base_cost: float = 100.0):
    """Create simple test DataFrame."""
    current = start_date
    timestamps = []
    while current <= end_date:
        timestamps.append(current)
        current += timedelta(hours=1)
    
    return pl.DataFrame({
        "timestamp": timestamps,
        "hourly_cost": [base_cost] * len(timestamps),
        "resource_id": ["test-resource"] * len(timestamps)
    })


class TestAutoIntensityCalculation:
    """Test automatic intensity calculation logic."""
    
    def test_daily_spike_intensity_calculation(self):
        """Test intensity calculation for daily spikes with different variance levels."""
        
        # Standard variance
        variance_config = {"daily_variance_pct": 50, "hourly_variance_pct": 100}
        intensity = calculate_anomaly_intensity("daily_spike", variance_config)
        
        print(f"Standard variance intensity: {intensity:.2f}")
        
        # Should be significantly higher than base 3.0 to achieve 4x separation
        assert intensity > 6.0, f"Calculated intensity {intensity} too low for 4x separation"
        
        # High variance scenario
        high_variance_config = {"daily_variance_pct": 100, "hourly_variance_pct": 200}
        high_intensity = calculate_anomaly_intensity("daily_spike", high_variance_config)
        
        print(f"High variance intensity: {high_intensity:.2f}")
        
        # Should be even higher for high variance
        assert high_intensity > intensity, "High variance should require higher intensity"
        assert high_intensity > 12.0, f"High variance intensity {high_intensity} insufficient"
        
    def test_step_down_intensity_calculation(self):
        """Test intensity calculation for step down anomalies."""
        
        variance_config = {"daily_variance_pct": 50, "hourly_variance_pct": 100}
        intensity = calculate_anomaly_intensity("daily_step_down", variance_config)
        
        print(f"Step down intensity: {intensity:.3f}")
        
        # Step down should be a fraction (reduction)
        assert intensity < 1.0, f"Step down intensity {intensity} should be < 1.0"
        assert intensity > 0.1, f"Step down intensity {intensity} too extreme"
        
    def test_intensity_validation(self):
        """Test intensity validation for effectiveness."""
        
        variance_config = {"daily_variance_pct": 100, "hourly_variance_pct": 200}
        intensity = calculate_anomaly_intensity("daily_spike", variance_config)
        
        validation = validate_intensity_effectiveness("daily_spike", intensity, variance_config)
        
        print(f"Validation results: {validation}")
        
        assert validation["is_sufficient"], "Calculated intensity should be sufficient"
        assert validation["estimated_separation"] >= 4.0, "Should achieve 4x separation target"
        
    def test_auto_calculation_in_anomaly_function(self):
        """Test that anomaly functions can auto-calculate intensity."""
        
        # Create test dataset
        test_df = create_test_dataframe(
            datetime(2024, 1, 1),
            datetime(2024, 1, 31),
            base_cost=100.0
        )
        
        # Configuration with variance_config but no intensity
        config = {
            "type": "daily_spike",
            "period": "Last 30 Days",
            "variance_config": {
                "daily_variance_pct": 50,
                "hourly_variance_pct": 100
            }
            # No intensity specified - should auto-calculate
        }
        
        # Should not raise an error and should apply calculated intensity
        result_df = apply_daily_spike(test_df, config, "test-resource")
        
        # Verify anomaly was applied (some costs should be different from base 100.0)
        unique_costs = result_df["hourly_cost"].unique().sort().to_list()
        
        print(f"Unique costs after auto-calculation: {unique_costs}")
        
        assert len(unique_costs) > 1, "Auto-calculation should have applied anomaly"
        
        # Should have both normal (100.0) and spiked costs
        assert 100.0 in unique_costs, "Should preserve normal baseline costs"
        
        # Should have significantly higher costs from auto-calculated intensity
        max_cost = max(unique_costs)
        assert max_cost > 600.0, f"Max cost {max_cost} suggests insufficient auto-calculated intensity"


if __name__ == "__main__":
    # Quick manual test
    test = TestAutoIntensityCalculation()
    test.test_daily_spike_intensity_calculation()
    test.test_step_down_intensity_calculation() 
    test.test_intensity_validation()
    test.test_auto_calculation_in_anomaly_function()