"""Comprehensive tests for configuration management."""

import os
import tempfile
from mnemosynth.core.config import MnemosynthConfig, DecayConfig, ContradictionConfig


class TestMnemosynthConfig:
    def setup_method(self):
        self.tmp = tempfile.mkdtemp()

    # ── Default values ────────────────────────────────────────

    def test_default_config(self):
        config = MnemosynthConfig(data_dir=self.tmp)
        assert config.embedding_model == "all-MiniLM-L6-v2"
        assert config.max_episodic_memories == 10000
        assert config.max_semantic_nodes == 5000

    def test_default_decay_config(self):
        config = MnemosynthConfig(data_dir=self.tmp)
        assert config.decay.enabled is True
        assert config.decay.half_life_days == 30.0
        assert config.decay.min_confidence == 0.1

    def test_default_contradiction_config(self):
        config = MnemosynthConfig(data_dir=self.tmp)
        assert config.contradiction.enabled is True
        assert config.contradiction.threshold == 0.85

    def test_default_dream_config(self):
        config = MnemosynthConfig(data_dir=self.tmp)
        assert config.dream.auto_schedule is False
        assert config.dream.interval_hours == 24
        assert config.dream.min_cluster_size == 3

    def test_default_digest_config(self):
        config = MnemosynthConfig(data_dir=self.tmp)
        assert config.digest.max_tokens == 150
        assert config.digest.top_k == 5

    def test_default_sentiment_config(self):
        config = MnemosynthConfig(data_dir=self.tmp)
        assert config.sentiment.enabled is True
        assert config.sentiment.boost_factor == 1.2

    # ── Paths ─────────────────────────────────────────────────

    def test_db_path(self):
        config = MnemosynthConfig(data_dir=self.tmp)
        assert config.db_path.endswith("memory.db")

    def test_vectors_dir(self):
        config = MnemosynthConfig(data_dir=self.tmp)
        assert config.vectors_dir.endswith("vectors")

    def test_graph_path(self):
        config = MnemosynthConfig(data_dir=self.tmp)
        assert config.graph_path.endswith("graph.db")

    def test_procedural_dir(self):
        config = MnemosynthConfig(data_dir=self.tmp)
        assert config.procedural_dir.endswith("procedures")

    # ── Directory creation ────────────────────────────────────

    def test_ensure_dirs(self):
        config = MnemosynthConfig(data_dir=os.path.join(self.tmp, "new_dir"))
        config.ensure_dirs()
        assert os.path.exists(config.data_dir)
        assert os.path.exists(config.vectors_dir)
        assert os.path.exists(config.procedural_dir)

    # ── Save and load ─────────────────────────────────────────

    def test_save_and_load(self):
        config = MnemosynthConfig(data_dir=os.path.join(self.tmp, "save_test"))
        config.decay.half_life_days = 60.0
        config.embedding_model = "custom-model"
        config.save()

        # Load fresh config from same dir
        config2 = MnemosynthConfig(data_dir=os.path.join(self.tmp, "save_test"))
        assert config2.decay.half_life_days == 60.0
        assert config2.embedding_model == "custom-model"

    # ── Environment variable override ─────────────────────────

    def test_env_var_override(self):
        env_dir = os.path.join(self.tmp, "env_test")
        os.environ["MNEMOSYNTH_DATA_DIR"] = env_dir
        try:
            config = MnemosynthConfig()  # No data_dir specified
            assert config.data_dir == env_dir
        finally:
            del os.environ["MNEMOSYNTH_DATA_DIR"]

    # ── Custom data_dir ───────────────────────────────────────

    def test_custom_data_dir(self):
        custom = os.path.join(self.tmp, "custom")
        config = MnemosynthConfig(data_dir=custom)
        assert config.data_dir == custom

    def test_tilde_expansion(self):
        config = MnemosynthConfig(data_dir="~/test_mnemosynth")
        assert "~" not in config.data_dir
        assert config.data_dir.startswith("/")
