import os

import pytest

from anomstack.config import env_vars, get_specs


def test_process_yaml_file():
    specs = get_specs()
    assert len(specs) > 0


def test_specs_structure():
    specs = get_specs()
    for batch_name, spec in specs.items():
        # Test required fields
        assert "metric_batch" in spec
        assert "db" in spec
        assert "table_key" in spec
        assert "model_path" in spec
        assert "model_configs" in spec
        assert "alert_methods" in spec
        assert "ingest_cron_schedule" in spec
        assert "train_cron_schedule" in spec
        assert "score_cron_schedule" in spec
        assert "alert_cron_schedule" in spec

        # Test field types
        assert isinstance(spec["metric_batch"], str)
        assert isinstance(spec["db"], str)
        assert isinstance(spec["table_key"], str)
        assert isinstance(spec["model_path"], str)
        assert isinstance(spec["model_configs"], list)
        assert isinstance(spec["alert_methods"], str)
        assert isinstance(spec["ingest_cron_schedule"], str)
        assert isinstance(spec["train_cron_schedule"], str)
        assert isinstance(spec["score_cron_schedule"], str)
        assert isinstance(spec["alert_cron_schedule"], str)


def test_default_values():
    specs = get_specs()
    for batch_name, spec in specs.items():
        # Test default values from defaults.yaml
        assert spec["model_combination_method"] == "mean"
        assert spec["train_max_n"] == 2500
        assert spec["train_min_n"] == 14
        assert spec["score_max_n"] == 25
        assert spec["alert_threshold"] == 0.8
        assert spec["change_threshold"] == 3.5
        assert spec["llmalert_recent_n"] == 5
        assert spec["delete_after_n_days"] == 365


def test_environment_variable_override():
    # Save original environment variables
    original_env = {}
    for var in env_vars:
        original_env[var] = os.environ.get(var)
        if var in os.environ:
            del os.environ[var]

    try:
        # Set test environment variables
        test_project_id = "test-project"
        test_model_path = "test-model-path"
        test_table_key = "test-table"

        os.environ["ANOMSTACK_GCP_PROJECT_ID"] = test_project_id
        os.environ["ANOMSTACK_MODEL_PATH"] = test_model_path
        os.environ["ANOMSTACK_TABLE_KEY"] = test_table_key

        specs = get_specs()

        # Test that environment variables override YAML values except for YAML_PRECEDENCE_PARAMS
        for batch_name, spec in specs.items():
            # These environment variables should always override their respective YAML values
            assert spec["gcp_project_id"] == test_project_id
            assert spec["model_path"] == test_model_path

            # table_key has YAML precedence - it should only be overridden if not defined in YAML
            # Check if this batch has a custom table_key in its YAML
            # If it does, YAML takes precedence; if not, env var should be used
            # We can't easily test this without loading individual YAML files,
            # so we'll accept either the env override or the YAML value
            assert spec["table_key"] is not None  # Just ensure it has some value
    finally:
        # Restore original environment variables
        for var, value in original_env.items():
            if value is not None:
                os.environ[var] = value
            elif var in os.environ:
                del os.environ[var]


def test_disabled_batches():
    specs = get_specs()
    for batch_name, spec in specs.items():
        # Test that disabled flags are boolean
        assert isinstance(spec.get("disable_batch", False), bool)
        assert isinstance(spec.get("disable_ingest", False), bool)
        assert isinstance(spec.get("disable_train", False), bool)
        assert isinstance(spec.get("disable_score", False), bool)
        assert isinstance(spec.get("disable_alert", False), bool)
        assert isinstance(spec.get("disable_change", False), bool)
        assert isinstance(spec.get("disable_llmalert", True), bool)
        assert isinstance(spec.get("disable_plot", False), bool)
        assert isinstance(spec.get("disable_summary", False), bool)
        assert isinstance(spec.get("disable_delete", False), bool)


def test_metrics_dir_parameter():
    # Test with default metrics directory
    specs_default = get_specs()
    assert len(specs_default) > 0

    # Test with custom metrics directory
    custom_metrics_dir = "./metrics"
    specs_custom = get_specs(metrics_dir=custom_metrics_dir)
    assert len(specs_custom) > 0

    # Test that specs are the same regardless of metrics_dir parameter
    assert specs_default == specs_custom


def test_invalid_metrics_dir():
    with pytest.raises(FileNotFoundError):
        get_specs(metrics_dir="./nonexistent_directory")


# Run the test
if __name__ == "__main__":
    pytest.main()
