"""Tests for taprune.config."""

from taprune.config import TapConfig, load_config, load_named_config


def test_load_named_config_default():
    """Bundled 'default' config loads and has expected keys."""
    cfg = load_named_config("default")
    assert isinstance(cfg, dict)
    assert "goal" in cfg
    assert "prompts" in cfg
    assert "tap" in cfg


def test_load_named_config_missing_returns_empty():
    """Non-existent config name returns empty dict."""
    assert load_named_config("nonexistent_config_xyz") == {}


def test_tap_config_from_dict_minimal():
    """TapConfig.from_dict works with minimal input."""
    cfg = TapConfig.from_dict({"goal": "test goal"})
    assert cfg.goal == "test goal"
    assert cfg.api == {}
    assert cfg.models == {}
    assert cfg.tap == {}
    assert cfg.target_system_prompt is None
    assert cfg.target_chat_history == []
    assert cfg.extra_parser is None


def test_tap_config_from_dict_none():
    """TapConfig.from_dict handles None input."""
    cfg = TapConfig.from_dict(None)
    assert cfg.goal == "Your attack goal here"


def test_tap_config_from_dict_full():
    """TapConfig.from_dict populates all fields from a full config."""
    d = {
        "goal": "my goal",
        "api": {"provider": "openai"},
        "models": {"attacker": "gpt-4o"},
        "tap": {"depth": 5},
        "target_context": {
            "system_prompt": "You are a test.",
            "chat_history": [{"role": "user", "content": "hi"}],
        },
        "starting_string": "Sure",
        "extra_parser": "raw_reply",
        "prompts": {
            "judge": "j",
            "off_topic": "o",
            "attacker": "a",
        },
    }
    cfg = TapConfig.from_dict(d)
    assert cfg.goal == "my goal"
    assert cfg.api["provider"] == "openai"
    assert cfg.models["attacker"] == "gpt-4o"
    assert cfg.tap["depth"] == 5
    assert cfg.target_system_prompt == "You are a test."
    assert len(cfg.target_chat_history) == 1
    assert cfg.starting_string == "Sure"
    assert cfg.extra_parser is not None
    assert cfg.raw is d


def test_tap_config_resolve_prompts():
    """resolve_prompts fills placeholders."""
    d = {
        "goal": "do something bad",
        "prompts": {
            "judge": "Objective: [[OBJECTIVE]] Start: [[STARTING_STRING]]",
            "off_topic": "Task: [[OBJECTIVE]]",
            "attacker": "Goal: [[OBJECTIVE]]",
        },
    }
    cfg = TapConfig.from_dict(d)
    prompts = cfg.resolve_prompts()
    assert "do something bad" in prompts["judge"]
    assert "[[OBJECTIVE]]" not in prompts["judge"]
    assert "do something bad" in prompts["off_topic"]
    assert "do something bad" in prompts["attacker"]


def test_load_config_from_file(tmp_path):
    """load_config reads a YAML file from disk."""
    f = tmp_path / "test.yaml"
    f.write_text("goal: file goal\ntap:\n  depth: 2\n")
    cfg = load_config(f)
    assert cfg["goal"] == "file goal"
    assert cfg["tap"]["depth"] == 2
