"""
Тесты конфигурации генератора.
"""

from pathlib import Path
from datetime import datetime, timedelta, timezone

import pytest
from generator import Config


class TestConfigValidation:
    """Тесты валидации конфигурации."""

    def test_tick_seconds_must_be_positive(self, base_config):
        """tick_seconds должен быть >= 1."""
        from dataclasses import replace
        with pytest.raises(ValueError, match="GEN_TICK_SECONDS"):
            replace(base_config, tick_seconds=0)

    def test_lambda_base_must_be_positive(self, base_config):
        """lambda_base_per_min должен быть >= 1."""
        from dataclasses import replace
        with pytest.raises(ValueError, match="GEN_LAMBDA_BASE_PER_MIN"):
            replace(base_config, lambda_base_per_min=0)

    def test_max_session_events_must_be_positive(self, base_config):
        """max_session_events должен быть >= 1."""
        from dataclasses import replace
        with pytest.raises(ValueError, match="GEN_MAX_SESSION_EVENTS"):
            replace(base_config, max_session_events=0)

    def test_max_active_sessions_must_be_less_than_population(self, base_config):
        """Потолок активных визитов должен быть меньше потолка популяции."""
        from dataclasses import replace
        with pytest.raises(ValueError, match="GEN_MAX_ACTIVE_SESSIONS"):
            replace(base_config, max_active_sessions=10, population_max=10)

    def test_new_user_probability_must_be_valid_share(self, base_config):
        """Вероятность нового пользователя должна быть долей от 0 до 1."""
        from dataclasses import replace
        with pytest.raises(ValueError, match="GEN_P_NEW_USER"):
            replace(base_config, p_new_user=1.5)

    def test_min_return_minutes_must_not_be_negative(self, base_config):
        """Кулдаун возврата не может быть отрицательным."""
        from dataclasses import replace
        with pytest.raises(ValueError, match="GEN_MIN_RETURN_MINUTES"):
            replace(base_config, min_return_minutes=-1)

    def test_data_dir_must_exist(self, base_config):
        """data_dir должен существовать."""
        from dataclasses import replace
        with pytest.raises(ValueError, match="does not exist"):
            replace(base_config, data_dir=Path("/nonexistent/path"))

    def test_valid_config_passes(self, base_config):
        """Валидная конфигурация создается без ошибок."""
        assert base_config.tick_seconds == 5
        assert base_config.lambda_base_per_min == 30
        assert base_config.jitter_pct == 20
        assert base_config.max_active_sessions < base_config.population_max

    def test_model_t0_is_normalized_to_utc(self, base_config):
        """model_t0 нормализуется к UTC даже при прямом создании Config."""
        from dataclasses import replace

        config = replace(
            base_config,
            model_t0=datetime(
                2026,
                1,
                1,
                13,
                0,
                tzinfo=timezone(timedelta(hours=3)),
            ),
        )

        assert config.model_t0 == datetime(2026, 1, 1, 10, 0, tzinfo=timezone.utc)


class TestConfigDefaults:
    """Тесты значений по умолчанию."""

    def test_default_lambda_base_per_min_is_calibrated_to_demo_scale(
        self, monkeypatch, data_dir
    ):
        """По умолчанию целевая интенсивность равна 30 событиям в минуту."""
        monkeypatch.setenv("GEN_DATA_DIR", str(data_dir))
        monkeypatch.delenv("GEN_LAMBDA_BASE_PER_MIN", raising=False)

        config = Config()

        assert config.lambda_base_per_min == 30

    def test_default_tick_seconds_is_5(self, data_dir):
        """По умолчанию tick_seconds = 5 (rev5)."""
        import os
        # Сохраняем текущее значение
        orig_value = os.environ.get("GEN_TICK_SECONDS")
        try:
            if "GEN_TICK_SECONDS" in os.environ:
                del os.environ["GEN_TICK_SECONDS"]
            config = Config(
                kafka_bootstrap_servers="localhost:9092",
                tick_seconds=int(os.getenv("GEN_TICK_SECONDS", "5")),
                lambda_base_per_min=30,
                jitter_pct=20,
                min_events_per_tick=1,
                max_events_per_tick=50,
                data_dir=data_dir,
                seed=None,
                enabled=True,
                metrics_port=9109,
            )
            assert config.tick_seconds == 5
        finally:
            if orig_value is not None:
                os.environ["GEN_TICK_SECONDS"] = orig_value

    def test_launch_profile_defaults_to_daily_wave(self, monkeypatch, data_dir):
        """По умолчанию выбран учебный профиль запуска daily-wave."""
        monkeypatch.setenv("GEN_DATA_DIR", str(data_dir))
        monkeypatch.delenv("GEN_LAUNCH_PROFILE", raising=False)

        config = Config()

        assert config.launch_profile == "daily-wave"

    def test_launch_profile_can_be_read_from_env(self, monkeypatch, data_dir):
        """Выбранный профиль запуска попадает в конфигурацию для логов."""
        monkeypatch.setenv("GEN_DATA_DIR", str(data_dir))
        monkeypatch.setenv("GEN_LAUNCH_PROFILE", "daily-wave")

        config = Config()

        assert config.launch_profile == "daily-wave"
