"""Tests for telemetry generation."""

import tempfile
from datetime import datetime
from pathlib import Path

import pytest
import yaml

from src.telemetry import TelemetryConfig, TelemetryGenerator


@pytest.fixture
def sample_config():
    """Create sample telemetry config."""
    return {
        "telemetry_generation": {
            "start_date": "2025-01-01",
            "end_date": "2025-01-02",
            "elements": {
                "acme-corp": None,
                "initech": "weekly_spike",
                "globex": None,
                "stark-industries": "weekly_step_up",
                "wayne-enterprises": None,
            },
        }
    }


@pytest.fixture
def config_file(sample_config, tmp_path):
    """Create temporary config file."""
    config_path = tmp_path / "test_config.yaml"
    with open(config_path, "w") as f:
        yaml.dump(sample_config, f)
    return config_path


def test_config_loading(config_file):
    """Test config loading from YAML."""
    config = TelemetryConfig.from_yaml(config_file)

    assert config.start_date == "2025-01-01"
    assert config.end_date == "2025-01-02"
    assert len(config.elements) == 5
    assert config.elements["initech"] == "weekly_spike"
    assert config.elements["acme-corp"] is None


def test_config_validation_minimum_elements():
    """Test config validation requires minimum 5 elements."""
    with pytest.raises(ValueError, match="At least 5 elements required"):
        TelemetryConfig(
            start_date="2025-01-01", end_date="2025-01-02", elements={"a": None}
        )


def test_config_validation_invalid_anomaly():
    """Test config validation rejects invalid anomaly types."""
    with pytest.raises(ValueError, match="Invalid anomaly type"):
        TelemetryConfig(
            start_date="2025-01-01",
            end_date="2025-01-02",
            elements={
                "a": None,
                "b": None,
                "c": None,
                "d": None,
                "e": "invalid_anomaly",
            },
        )


def test_generator_basic_generation(config_file):
    """Test basic telemetry generation without anomalies."""
    config = TelemetryConfig.from_yaml(config_file)
    generator = TelemetryGenerator(config)

    df = generator.generate()

    # Check structure
    assert list(df.columns) == ["timestamp", "element_id", "unit_value"]

    # Check data
    assert len(df) > 0
    assert df["element_id"].n_unique() == 5
    assert (df["unit_value"] > 0).all()

    # Check timestamp range (hourly for 2 days)
    # From 2025-01-01 00:00 to 2025-01-02 00:00 inclusive = 25 hours
    unique_timestamps = df["timestamp"].n_unique()
    assert unique_timestamps == 25


def test_generator_with_anomalies(config_file):
    """Test telemetry generation with anomalies."""
    config = TelemetryConfig.from_yaml(config_file)
    generator = TelemetryGenerator(config)

    df = generator.generate()

    # Check that elements with anomalies exist
    spike_element = df.filter(df["element_id"] == "initech")
    step_element = df.filter(df["element_id"] == "stark-industries")

    assert len(spike_element) > 0
    assert len(step_element) > 0

    # Weekly spike should have some elevated values
    # (Won't test exact values since timing is deterministic but complex)
    assert spike_element["unit_value"].max() > spike_element["unit_value"].mean()

    # Weekly step up should show progression
    # (Again, won't test exact pattern but verify data exists)
    assert step_element["unit_value"].std() > 0


def test_distribution_automatic():
    """Test automatic distribution creates outliers."""
    config = TelemetryConfig(
        start_date="2025-01-01",
        end_date="2025-01-02",  # Must be after start_date
        elements={
            "e1": None,
            "e2": None,
            "e3": None,
            "e4": None,
            "e5": None,
            "e6": None,
            "e7": None,
        },
    )

    generator = TelemetryGenerator(config)
    df = generator.generate()

    # Calculate average value per element using proper Polars aggregation
    import polars as pl
    element_avgs = (
        df.group_by("element_id")
        .agg(pl.col("unit_value").mean().alias("avg_value"))
        .sort("avg_value")
    )

    # Check we have variation (not all equal)
    values = element_avgs["avg_value"].to_list()
    assert max(values) > min(values) * 2  # At least 2x difference


def test_deterministic_generation(config_file):
    """Test that generation is deterministic."""
    config = TelemetryConfig.from_yaml(config_file)

    generator1 = TelemetryGenerator(config)
    df1 = generator1.generate()

    generator2 = TelemetryGenerator(config)
    df2 = generator2.generate()

    # Should produce identical results
    assert df1.equals(df2)


def test_config_to_yaml_dict(config_file):
    """Test config serialization to YAML dict."""
    config = TelemetryConfig.from_yaml(config_file)
    yaml_dict = config.to_yaml_dict()

    assert "telemetry_generation" in yaml_dict
    assert "start_date" in yaml_dict["telemetry_generation"]
    assert "elements" in yaml_dict["telemetry_generation"]
