# region test_llm_prompt_templates [TYPE Module]
# @SEMANTICS: tests, llm, prompts, templates, settings
# @PURPOSE: Validate normalization and rendering behavior for configurable LLM prompt templates.
# @LAYER Domain Tests
# @RELATION  DEPENDS_ON -> [llm_prompt_templates]
# @INVARIANT  All required prompt keys remain available after normalization.

from src.services.llm_prompt_templates import (
    DEFAULT_LLM_ASSISTANT_SETTINGS,
    DEFAULT_LLM_PROMPTS,
    DEFAULT_LLM_PROVIDER_BINDINGS,
    is_multimodal_model,
    normalize_llm_settings,
    render_prompt,
    resolve_bound_provider_id,
)


# region test_normalize_llm_settings_adds_default_prompts [TYPE Function]
# @RELATION  BINDS_TO -> test_llm_prompt_templates
# @PURPOSE: Ensure legacy/partial llm settings are expanded with all prompt defaults.
# @PRE  Input llm settings do not contain complete prompts object.
# @POST  Returned structure includes required prompt templates with fallback defaults.
def test_normalize_llm_settings_adds_default_prompts():
    normalized = normalize_llm_settings({"default_provider": "x"})

    assert "prompts" in normalized
    assert "provider_bindings" in normalized
    assert normalized["default_provider"] == "x"
    for key in DEFAULT_LLM_PROMPTS:
        assert key in normalized["prompts"]
        assert isinstance(normalized["prompts"][key], str)
    for key in DEFAULT_LLM_PROVIDER_BINDINGS:
        assert key in normalized["provider_bindings"]
    for key in DEFAULT_LLM_ASSISTANT_SETTINGS:
        assert key in normalized


# endregion test_normalize_llm_settings_adds_default_prompts


# region test_normalize_llm_settings_keeps_custom_prompt_values [TYPE Function]
# @RELATION  BINDS_TO -> test_llm_prompt_templates
# @PURPOSE: Ensure user-customized prompt values are preserved during normalization.
# @PRE  Input llm settings contain custom prompt override.
# @POST  Custom prompt value remains unchanged in normalized output.
def test_normalize_llm_settings_keeps_custom_prompt_values():
    custom = "Doc for {dataset_name} using {columns_json}"
    normalized = normalize_llm_settings({"prompts": {"documentation_prompt": custom}})

    assert normalized["prompts"]["documentation_prompt"] == custom


# endregion test_normalize_llm_settings_keeps_custom_prompt_values


# region test_render_prompt_replaces_known_placeholders [TYPE Function]
# @RELATION  BINDS_TO -> test_llm_prompt_templates
# @PURPOSE: Ensure template placeholders are deterministically replaced.
# @PRE  Template contains placeholders matching provided variables.
# @POST  Rendered prompt string contains substituted values.
def test_render_prompt_replaces_known_placeholders():
    rendered = render_prompt(
        "Hello {name}, diff={diff}",
        {"name": "bot", "diff": "A->B"},
    )

    assert rendered == "Hello bot, diff=A->B"


# endregion test_render_prompt_replaces_known_placeholders


# region test_is_multimodal_model_detects_known_vision_models [TYPE Function]
# @RELATION  BINDS_TO -> test_llm_prompt_templates
# @PURPOSE: Ensure multimodal model detection recognizes common vision-capable model names.
def test_is_multimodal_model_detects_known_vision_models():
    assert is_multimodal_model("gpt-4o") is True
    assert is_multimodal_model("claude-3-5-sonnet") is True
    assert is_multimodal_model("stepfun/step-3.5-flash:free", "openrouter") is False
    assert is_multimodal_model("text-only-model") is False


# endregion test_is_multimodal_model_detects_known_vision_models


# region test_resolve_bound_provider_id_prefers_binding_then_default [TYPE Function]
# @RELATION  BINDS_TO -> test_llm_prompt_templates
# @PURPOSE: Verify provider binding resolution priority.
def test_resolve_bound_provider_id_prefers_binding_then_default():
    settings = {
        "default_provider": "default-1",
        "provider_bindings": {"documentation": "doc-1"},
    }
    assert resolve_bound_provider_id(settings, "documentation") == "doc-1"
    assert resolve_bound_provider_id(settings, "git_commit") == "default-1"


# endregion test_resolve_bound_provider_id_prefers_binding_then_default


# region test_normalize_llm_settings_keeps_assistant_planner_settings [TYPE Function]
# @RELATION  BINDS_TO -> test_llm_prompt_templates
# @PURPOSE: Ensure assistant planner provider/model fields are preserved and normalized.
def test_normalize_llm_settings_keeps_assistant_planner_settings():
    normalized = normalize_llm_settings(
        {
            "assistant_planner_provider": "provider-a",
            "assistant_planner_model": "gpt-4.1-mini",
        }
    )
    assert normalized["assistant_planner_provider"] == "provider-a"
    assert normalized["assistant_planner_model"] == "gpt-4.1-mini"


# endregion test_normalize_llm_settings_keeps_assistant_planner_settings


# endregion test_llm_prompt_templates
