"""Tests for config overlay system."""
import os
import json
import tempfile
import yaml
import pytest


def test_deep_merge_dicts():
    """Deep merge should recursively merge dicts."""
    from config_overlay import deep_merge
    base = {"a": {"b": 1, "c": 2}, "d": 3}
    overlay = {"a": {"b": 10, "e": 5}}
    result = deep_merge(base, overlay)
    assert result == {"a": {"b": 10, "c": 2, "e": 5}, "d": 3}


def test_deep_merge_lists_replaced():
    """Lists should be replaced, not extended."""
    from config_overlay import deep_merge
    base = {"items": [1, 2, 3]}
    overlay = {"items": [4, 5]}
    result = deep_merge(base, overlay)
    assert result == {"items": [4, 5]}


def test_deep_merge_scalars_overridden():
    """Scalar values should be overridden by overlay."""
    from config_overlay import deep_merge
    base = {"name": "base", "count": 10}
    overlay = {"name": "override", "count": 20}
    result = deep_merge(base, overlay)
    assert result == {"name": "override", "count": 20}


def test_deep_merge_none_removes_key():
    """None in overlay should remove the key from base."""
    from config_overlay import deep_merge
    base = {"a": 1, "b": 2, "c": 3}
    overlay = {"b": None}
    result = deep_merge(base, overlay)
    assert result == {"a": 1, "c": 3}


def test_deep_merge_empty_overlay():
    """Empty overlay should return base unchanged."""
    from config_overlay import deep_merge
    base = {"a": 1, "b": {"c": 2}}
    result = deep_merge(base, {})
    assert result == base


def test_load_config_no_env(tmp_path):
    """Load config without overlay should return base."""
    from config_overlay import load_config
    base = {"model": "test", "agent": {"max_turns": 10}}
    path = tmp_path / "config.yaml"
    path.write_text(yaml.dump(base))
    result = load_config(str(path))
    assert result == base


def test_load_config_with_overlay(tmp_path):
    """Load config with overlay should merge."""
    from config_overlay import load_config
    base = {"model": "base", "agent": {"max_turns": 10, "verbose": False}}
    overlay = {"model": "override", "agent": {"verbose": True}}
    (tmp_path / "config.yaml").write_text(yaml.dump(base))
    (tmp_path / "config.dev.yaml").write_text(yaml.dump(overlay))
    result = load_config(str(tmp_path / "config.yaml"), env="dev")
    assert result["model"] == "override"
    assert result["agent"]["max_turns"] == 10
    assert result["agent"]["verbose"] is True


def test_load_config_missing_overlay(tmp_path):
    """Missing overlay should silently return base."""
    from config_overlay import load_config
    base = {"model": "base"}
    (tmp_path / "config.yaml").write_text(yaml.dump(base))
    result = load_config(str(tmp_path / "config.yaml"), env="nonexistent")
    assert result == base


def test_find_config(tmp_path):
    """find_config should locate base and overlay."""
    from config_overlay import find_config
    base = tmp_path / "config.yaml"
    base.write_text("a: 1")
    overlay = tmp_path / "config.prod.yaml"
    overlay.write_text("a: 2")
    b, o = find_config(str(base), "prod")
    assert b == base
    assert o == overlay


def test_list_overlays(tmp_path):
    """list_overlays should find all overlay files."""
    from config_overlay import list_overlays
    (tmp_path / "config.yaml").write_text("a: 1")
    (tmp_path / "config.dev.yaml").write_text("a: 2")
    (tmp_path / "config.prod.yaml").write_text("a: 3")
    overlays = list_overlays(str(tmp_path / "config.yaml"))
    envs = [o['env'] for o in overlays]
    assert 'dev' in envs
    assert 'prod' in envs


def test_detect_env_from_var(tmp_path, monkeypatch):
    """detect_env should check TIMMY_ENV first."""
    from config_overlay import detect_env
    monkeypatch.setenv("TIMMY_ENV", "prod")
    assert detect_env() == "prod"


def test_detect_env_fallback(tmp_path, monkeypatch):
    """detect_env should fall back through vars."""
    from config_overlay import detect_env
    monkeypatch.delenv("TIMMY_ENV", raising=False)
    monkeypatch.delenv("HERMES_ENV", raising=False)
    monkeypatch.setenv("ENVIRONMENT", "cron")
    assert detect_env() == "cron"


def test_real_config_overlay():
    """Test against actual config files in the repo."""
    import sys
    sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
    from config_overlay import load_config

    base_path = os.path.join(os.path.dirname(__file__), '..', 'config.yaml')
    if os.path.exists(base_path):
        config = load_config(base_path, env='dev')
        assert config['model']['default'] == 'qwen3:30b'  # dev overrides
        assert config['agent']['max_turns'] == 50  # dev overrides
        assert 'terminal' in config  # base keys preserved
