"""Tests for config-driven compat layer behavior.

Verifies that ENABLE_ANTHROPIC_COMPAT and ENABLE_RESPONSES_API control router
registration correctly: endpoints return 404 when their layer is disabled,
/v1/chat/completions and /v1/models always work, and config defaults/env
parsing are correct.
"""

import json
import os
import sys
import types
import unittest
from unittest.mock import patch, AsyncMock, MagicMock

import pytest


# ---------------------------------------------------------------------------
# Config unit tests (no app import needed)
# ---------------------------------------------------------------------------

class TestConfigDefaults:
    """Default values for compat config flags."""

    def _reload_config(self, env_overrides=None):
        """Reload config module with optional env var overrides."""
        orig = sys.modules.get("config")
        try:
            if "config" in sys.modules:
                del sys.modules["config"]
            with patch.dict(os.environ, env_overrides or {}, clear=False):
                import config
                return config
        finally:
            if orig is not None:
                sys.modules["config"] = orig
            elif "config" in sys.modules:
                del sys.modules["config"]

    def test_anthropic_compat_defaults_true(self):
        """ENABLE_ANTHROPIC_COMPAT defaults to True when env var is unset."""
        env = os.environ.copy()
        env.pop("HARBOR_BOOST_ANTHROPIC_COMPAT", None)
        if "config" in sys.modules:
            orig = sys.modules["config"]
        else:
            orig = None
        try:
            if "config" in sys.modules:
                del sys.modules["config"]
            with patch.dict(os.environ, env, clear=True):
                import config
                assert config.ENABLE_ANTHROPIC_COMPAT.value is True
        finally:
            if orig is not None:
                sys.modules["config"] = orig
            elif "config" in sys.modules:
                del sys.modules["config"]

    def test_responses_api_defaults_true(self):
        """ENABLE_RESPONSES_API defaults to True when env var is unset."""
        env = os.environ.copy()
        env.pop("HARBOR_BOOST_RESPONSES_API", None)
        if "config" in sys.modules:
            orig = sys.modules["config"]
        else:
            orig = None
        try:
            if "config" in sys.modules:
                del sys.modules["config"]
            with patch.dict(os.environ, env, clear=True):
                import config
                assert config.ENABLE_RESPONSES_API.value is True
        finally:
            if orig is not None:
                sys.modules["config"] = orig
            elif "config" in sys.modules:
                del sys.modules["config"]

    def test_anthropic_compat_env_name(self):
        """Config reads from HARBOR_BOOST_ANTHROPIC_COMPAT env var."""
        if "config" in sys.modules:
            orig = sys.modules["config"]
        else:
            orig = None
        try:
            if "config" in sys.modules:
                del sys.modules["config"]
            with patch.dict(os.environ, {"HARBOR_BOOST_ANTHROPIC_COMPAT": "false"}, clear=False):
                import config
                assert config.ENABLE_ANTHROPIC_COMPAT.value is False
                assert config.ENABLE_ANTHROPIC_COMPAT.name == "HARBOR_BOOST_ANTHROPIC_COMPAT"
        finally:
            if orig is not None:
                sys.modules["config"] = orig
            elif "config" in sys.modules:
                del sys.modules["config"]

    def test_responses_api_env_name(self):
        """Config reads from HARBOR_BOOST_RESPONSES_API env var."""
        if "config" in sys.modules:
            orig = sys.modules["config"]
        else:
            orig = None
        try:
            if "config" in sys.modules:
                del sys.modules["config"]
            with patch.dict(os.environ, {"HARBOR_BOOST_RESPONSES_API": "false"}, clear=False):
                import config
                assert config.ENABLE_RESPONSES_API.value is False
                assert config.ENABLE_RESPONSES_API.name == "HARBOR_BOOST_RESPONSES_API"
        finally:
            if orig is not None:
                sys.modules["config"] = orig
            elif "config" in sys.modules:
                del sys.modules["config"]


class TestConfigBoolParsing:
    """Bool config parsing for various string inputs."""

    def _reload_config_with(self, key, value):
        orig = sys.modules.get("config")
        try:
            if "config" in sys.modules:
                del sys.modules["config"]
            with patch.dict(os.environ, {key: value}, clear=False):
                import config
                return config
        finally:
            if orig is not None:
                sys.modules["config"] = orig
            elif "config" in sys.modules:
                del sys.modules["config"]

    def test_true_string(self):
        cfg = self._reload_config_with("HARBOR_BOOST_ANTHROPIC_COMPAT", "true")
        assert cfg.ENABLE_ANTHROPIC_COMPAT.value is True

    def test_false_string(self):
        cfg = self._reload_config_with("HARBOR_BOOST_ANTHROPIC_COMPAT", "false")
        assert cfg.ENABLE_ANTHROPIC_COMPAT.value is False

    def test_one_is_true(self):
        cfg = self._reload_config_with("HARBOR_BOOST_ANTHROPIC_COMPAT", "1")
        assert cfg.ENABLE_ANTHROPIC_COMPAT.value is True

    def test_zero_is_false(self):
        cfg = self._reload_config_with("HARBOR_BOOST_ANTHROPIC_COMPAT", "0")
        assert cfg.ENABLE_ANTHROPIC_COMPAT.value is False

    def test_yes_is_true(self):
        cfg = self._reload_config_with("HARBOR_BOOST_ANTHROPIC_COMPAT", "yes")
        assert cfg.ENABLE_ANTHROPIC_COMPAT.value is True

    def test_on_is_true(self):
        cfg = self._reload_config_with("HARBOR_BOOST_ANTHROPIC_COMPAT", "on")
        assert cfg.ENABLE_ANTHROPIC_COMPAT.value is True

    def test_TRUE_uppercase(self):
        cfg = self._reload_config_with("HARBOR_BOOST_ANTHROPIC_COMPAT", "TRUE")
        assert cfg.ENABLE_ANTHROPIC_COMPAT.value is True

    def test_False_mixed_case(self):
        cfg = self._reload_config_with("HARBOR_BOOST_ANTHROPIC_COMPAT", "False")
        assert cfg.ENABLE_ANTHROPIC_COMPAT.value is False

    def test_random_string_is_false(self):
        """Non-boolean strings resolve to False (not true/1/yes/on)."""
        cfg = self._reload_config_with("HARBOR_BOOST_ANTHROPIC_COMPAT", "banana")
        assert cfg.ENABLE_ANTHROPIC_COMPAT.value is False

    def test_empty_string_is_false(self):
        cfg = self._reload_config_with("HARBOR_BOOST_ANTHROPIC_COMPAT", "")
        assert cfg.ENABLE_ANTHROPIC_COMPAT.value is False

    def test_responses_api_same_parsing(self):
        """ENABLE_RESPONSES_API uses the same bool parsing."""
        cfg = self._reload_config_with("HARBOR_BOOST_RESPONSES_API", "false")
        assert cfg.ENABLE_RESPONSES_API.value is False
        cfg2 = self._reload_config_with("HARBOR_BOOST_RESPONSES_API", "1")
        assert cfg2.ENABLE_RESPONSES_API.value is True


class TestConfigResolvedAtImportTime:
    """Config values are resolved once at import time, not per-request."""

    def test_value_resolved_at_init(self):
        """Config.__init__ calls resolve_value() and caches the result."""
        from config import Config
        cfg = Config("TEST_VAR_NOT_SET", bool, "true")
        assert cfg.value is True
        # Changing the env after init has no effect
        os.environ["TEST_VAR_NOT_SET"] = "false"
        assert cfg.value is True
        os.environ.pop("TEST_VAR_NOT_SET", None)

    def test_value_is_property_not_function(self):
        """Config.value is a property returning the cached __value__."""
        from config import Config
        cfg = Config("TEST_PROP_CHECK", bool, "false")
        assert cfg.value is cfg.__value__
        assert cfg.value is False


# ---------------------------------------------------------------------------
# Router registration tests — require reloading main with different configs
# ---------------------------------------------------------------------------

def _make_fresh_app(anthropic_compat="true", responses_api="true"):
    """Create a fresh FastAPI app with the given compat layer config.

    Reloads config and main modules so that the module-level ``if`` guards
    in main.py re-evaluate with the new environment.
    """
    from starlette.testclient import TestClient

    # Preserve original modules to restore later
    saved = {}
    for mod_name in ("config", "main", "anthropic_compat", "responses_compat",
                     "auth", "compat_utils", "selection", "mods",
                     "llm_registry"):
        saved[mod_name] = sys.modules.get(mod_name)

    env_patch = {
        "HARBOR_BOOST_ANTHROPIC_COMPAT": anthropic_compat,
        "HARBOR_BOOST_RESPONSES_API": responses_api,
    }

    # Remove modules that need reloading
    for mod_name in ("config", "main", "auth", "anthropic_compat", "responses_compat"):
        sys.modules.pop(mod_name, None)

    with patch.dict(os.environ, env_patch, clear=False):
        import config as cfg
        cfg.BOOST_AUTH = []  # disable auth for tests

        import main as main_mod

    client = TestClient(main_mod.app, raise_server_exceptions=False)

    # Restore original modules for test isolation
    def restore():
        for mod_name, mod in saved.items():
            if mod is not None:
                sys.modules[mod_name] = mod
            else:
                sys.modules.pop(mod_name, None)

    return client, main_mod, restore


class TestAnthropicCompatDisabled:
    """When ENABLE_ANTHROPIC_COMPAT is false, /v1/messages is not registered."""

    def test_messages_returns_404(self):
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="true"
        )
        try:
            resp = client.post(
                "/v1/messages",
                json={
                    "model": "test-model",
                    "max_tokens": 100,
                    "messages": [{"role": "user", "content": "hi"}],
                },
                headers={"x-api-key": "test"},
            )
            assert resp.status_code in (404, 405), (
                f"Expected 404/405 when Anthropic compat disabled, got {resp.status_code}"
            )
        finally:
            restore()

    def test_count_tokens_returns_404(self):
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="true"
        )
        try:
            resp = client.post(
                "/v1/messages/count_tokens",
                json={
                    "model": "test-model",
                    "messages": [{"role": "user", "content": "hi"}],
                },
                headers={"x-api-key": "test"},
            )
            assert resp.status_code in (404, 405), (
                f"Expected 404/405 when Anthropic compat disabled, got {resp.status_code}"
            )
        finally:
            restore()


class TestResponsesApiDisabled:
    """When ENABLE_RESPONSES_API is false, /v1/responses is not registered."""

    def test_responses_returns_404(self):
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="true", responses_api="false"
        )
        try:
            resp = client.post(
                "/v1/responses",
                json={"model": "test-model", "input": "hello"},
                headers={"authorization": "Bearer test"},
            )
            assert resp.status_code in (404, 405), (
                f"Expected 404/405 when Responses API disabled, got {resp.status_code}"
            )
        finally:
            restore()


class TestBothDisabled:
    """When both compat layers are disabled, core endpoints still work."""

    @patch("mapper.list_downstream", new_callable=AsyncMock)
    @patch("mapper.workflow_models", return_value=[])
    def test_chat_completions_still_works(self, _wf, mock_downstream):
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            # Patch mapper on the freshly loaded main module
            main_mod.mapper.list_downstream = mock_downstream
            mock_downstream.return_value = []

            # /v1/chat/completions is always registered (though it will fail
            # at the mapper level without a model — we just check it's not 404)
            resp = client.post(
                "/v1/chat/completions",
                json={"model": "test-model", "messages": [{"role": "user", "content": "hi"}]},
                headers={"authorization": "Bearer test"},
            )
            # Should not be 404 (route exists) — will be 400/500 due to no
            # backend, but that proves the route is registered
            assert resp.status_code != 404, "chat/completions should be registered"
        finally:
            restore()

    @patch("mapper.list_downstream", new_callable=AsyncMock)
    @patch("mapper.workflow_models", return_value=[])
    def test_models_endpoint_still_works(self, _wf, mock_downstream):
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            main_mod.mapper.list_downstream = mock_downstream
            main_mod.mapper.workflow_models = _wf
            mock_downstream.return_value = [
                {"id": "test-model", "object": "model", "created": 0, "owned_by": "test"},
            ]
            main_mod.config.BOOST_MODS.__value__ = []
            main_mod.config.SERVE_BASE_MODELS.__value__ = True
            main_mod.config.MODEL_FILTER.__value__ = []

            resp = client.get(
                "/v1/models",
                headers={"authorization": "Bearer test"},
            )
            assert resp.status_code == 200
            data = resp.json()
            assert data["object"] == "list"
            assert len(data["data"]) == 1
        finally:
            restore()

    def test_messages_returns_404(self):
        client, _, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            resp = client.post(
                "/v1/messages",
                json={
                    "model": "test-model",
                    "max_tokens": 100,
                    "messages": [{"role": "user", "content": "hi"}],
                },
            )
            assert resp.status_code in (404, 405)
        finally:
            restore()

    def test_responses_returns_404(self):
        client, _, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            resp = client.post(
                "/v1/responses",
                json={"model": "test-model", "input": "hello"},
            )
            assert resp.status_code in (404, 405)
        finally:
            restore()


class TestBothEnabled:
    """When both compat layers are enabled, all endpoints are reachable."""

    @patch("mapper.list_downstream", new_callable=AsyncMock)
    @patch("mapper.workflow_models", return_value=[])
    def test_models_works(self, _wf, mock_downstream):
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="true", responses_api="true"
        )
        try:
            main_mod.mapper.list_downstream = mock_downstream
            main_mod.mapper.workflow_models = _wf
            mock_downstream.return_value = [
                {"id": "m1", "object": "model", "created": 0, "owned_by": "test"},
            ]
            main_mod.config.BOOST_MODS.__value__ = []
            main_mod.config.SERVE_BASE_MODELS.__value__ = True
            main_mod.config.MODEL_FILTER.__value__ = []

            resp = client.get("/v1/models", headers={"authorization": "Bearer test"})
            assert resp.status_code == 200
        finally:
            restore()

    def test_messages_reachable(self):
        """POST /v1/messages reaches the Anthropic handler (not 404)."""
        client, _, restore = _make_fresh_app(
            anthropic_compat="true", responses_api="true"
        )
        try:
            resp = client.post(
                "/v1/messages",
                json={
                    "model": "test-model",
                    "max_tokens": 100,
                    "messages": [{"role": "user", "content": "hi"}],
                },
            )
            # Not 404 — the route exists. It may fail at mapper resolution
            # but the handler was invoked.
            assert resp.status_code != 404, "messages should be registered when enabled"
        finally:
            restore()

    def test_responses_reachable(self):
        """POST /v1/responses reaches the Responses handler (not 404)."""
        client, _, restore = _make_fresh_app(
            anthropic_compat="true", responses_api="true"
        )
        try:
            resp = client.post(
                "/v1/responses",
                json={"model": "test-model", "input": "hello"},
            )
            assert resp.status_code != 404, "responses should be registered when enabled"
        finally:
            restore()

    @patch("mapper.list_downstream", new_callable=AsyncMock)
    @patch("mapper.workflow_models", return_value=[])
    def test_chat_completions_works(self, _wf, mock_downstream):
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="true", responses_api="true"
        )
        try:
            main_mod.mapper.list_downstream = mock_downstream
            mock_downstream.return_value = []

            resp = client.post(
                "/v1/chat/completions",
                json={"model": "test-model", "messages": [{"role": "user", "content": "hi"}]},
                headers={"authorization": "Bearer test"},
            )
            assert resp.status_code != 404, "chat/completions should be registered"
        finally:
            restore()


class TestModelsEndpointIndependentOfCompat:
    """The /v1/models endpoint works regardless of compat layer config."""

    @patch("mapper.list_downstream", new_callable=AsyncMock)
    @patch("mapper.workflow_models", return_value=[])
    def test_models_with_anthropic_only(self, _wf, mock_downstream):
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="true", responses_api="false"
        )
        try:
            main_mod.mapper.list_downstream = mock_downstream
            main_mod.mapper.workflow_models = _wf
            mock_downstream.return_value = [
                {"id": "m1", "object": "model", "created": 0, "owned_by": "test"},
            ]
            main_mod.config.BOOST_MODS.__value__ = []
            main_mod.config.SERVE_BASE_MODELS.__value__ = True
            main_mod.config.MODEL_FILTER.__value__ = []

            resp = client.get("/v1/models", headers={"authorization": "Bearer test"})
            assert resp.status_code == 200
        finally:
            restore()

    @patch("mapper.list_downstream", new_callable=AsyncMock)
    @patch("mapper.workflow_models", return_value=[])
    def test_models_with_responses_only(self, _wf, mock_downstream):
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="true"
        )
        try:
            main_mod.mapper.list_downstream = mock_downstream
            main_mod.mapper.workflow_models = _wf
            mock_downstream.return_value = [
                {"id": "m1", "object": "model", "created": 0, "owned_by": "test"},
            ]
            main_mod.config.BOOST_MODS.__value__ = []
            main_mod.config.SERVE_BASE_MODELS.__value__ = True
            main_mod.config.MODEL_FILTER.__value__ = []

            resp = client.get("/v1/models", headers={"authorization": "Bearer test"})
            assert resp.status_code == 200
        finally:
            restore()

    @patch("mapper.list_downstream", new_callable=AsyncMock)
    @patch("mapper.workflow_models", return_value=[])
    def test_models_with_none(self, _wf, mock_downstream):
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            main_mod.mapper.list_downstream = mock_downstream
            main_mod.mapper.workflow_models = _wf
            mock_downstream.return_value = [
                {"id": "m1", "object": "model", "created": 0, "owned_by": "test"},
            ]
            main_mod.config.BOOST_MODS.__value__ = []
            main_mod.config.SERVE_BASE_MODELS.__value__ = True
            main_mod.config.MODEL_FILTER.__value__ = []

            resp = client.get("/v1/models", headers={"authorization": "Bearer test"})
            assert resp.status_code == 200
        finally:
            restore()

    @patch("mapper.list_downstream", new_callable=AsyncMock)
    @patch("mapper.workflow_models", return_value=[])
    def test_models_with_both(self, _wf, mock_downstream):
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="true", responses_api="true"
        )
        try:
            main_mod.mapper.list_downstream = mock_downstream
            main_mod.mapper.workflow_models = _wf
            mock_downstream.return_value = [
                {"id": "m1", "object": "model", "created": 0, "owned_by": "test"},
            ]
            main_mod.config.BOOST_MODS.__value__ = []
            main_mod.config.SERVE_BASE_MODELS.__value__ = True
            main_mod.config.MODEL_FILTER.__value__ = []

            resp = client.get("/v1/models", headers={"authorization": "Bearer test"})
            assert resp.status_code == 200
        finally:
            restore()


class TestHealthEndpointIndependentOfCompat:
    """Health and root endpoints work regardless of compat config."""

    def test_health_both_disabled(self):
        client, _, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            resp = client.get("/health")
            assert resp.status_code == 200
            assert resp.json()["status"] == "ok"
        finally:
            restore()

    def test_root_both_disabled(self):
        client, _, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            resp = client.get("/")
            assert resp.status_code == 200
            assert resp.json()["status"] == "ok"
        finally:
            restore()


class TestMainPyHttpHandlerBranches:
    """Cover remaining un-hit main.py HTTP handler paths (e.g. 250 filter, 240-242 proxy modules, 387-389 invalid JSON, 411-412 direct task, _is_anthropic + _to_anthropic) via HTTP in this non-prior test file only."""

    @patch("mapper.list_downstream", new_callable=AsyncMock)
    @patch("mapper.workflow_models", return_value=[])
    def test_models_filter_and_module_proxy_branches_hit_250_240(self, _wf, mock_downstream):
        """Exercise _list_models 240-242 (registry.get + get_proxy) and 250 (matches_filter when MODEL_FILTER set)."""
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            main_mod.mapper.list_downstream = mock_downstream
            main_mod.mapper.workflow_models = _wf
            mock_downstream.return_value = [
                {"id": "test-model", "object": "model", "created": 0, "owned_by": "test"},
            ]
            main_mod.config.BOOST_MODS.__value__ = ["testmod"]
            main_mod.config.SERVE_BASE_MODELS.__value__ = True
            main_mod.config.MODEL_FILTER.__value__ = {"id": "test-model"}

            # Make registry.get return non-None to enter 242
            mock_mod = MagicMock()
            mock_reg = MagicMock()
            mock_reg.get.return_value = mock_mod
            main_mod.mods.registry = mock_reg
            # Stub get_proxy_model to avoid side effects in proxy creation
            main_mod.mapper.get_proxy_model = MagicMock(return_value={
                "id": "testmod-test-model", "object": "model", "created": 0, "owned_by": "boost"
            })

            resp = client.get("/v1/models", headers={"authorization": "Bearer test"})
            assert resp.status_code == 200
            data = resp.json()
            # At least base + proxy should be present (filter passes)
            ids = [m.get("id") for m in data.get("data", [])]
            assert "test-model" in ids or "testmod-test-model" in ids
        finally:
            restore()

    def test_chat_direct_task_hits_411_412(self):
        """Exercise chat post 411-412 direct task early return (is_direct True, no workflow)."""
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            # Setup for chat path to reach the if without full backend
            mock_list = AsyncMock()
            main_mod.mapper.list_downstream = mock_list
            main_mod.mapper.resolve_request_config = MagicMock(return_value={
                "url": "http://fake:8080",
                "api_key": "sk-test",
                "headers": {"Authorization": "Bearer sk-test"},
                "model": "test-model",
                "module": None,
                "workflow": None,
                "params": {},
            })
            main_mod.mapper.is_direct_task = MagicMock(return_value=True)

            # Fake the LLM class used inside main (post reload) so direct .chat_completion doesn't hit network
            fake_proxy = MagicMock()
            fake_proxy.chat_completion = AsyncMock(return_value={
                "id": "direct-1",
                "choices": [{"message": {"role": "assistant", "content": "direct ok"}}]
            })
            fake_proxy.workflow = None
            fake_proxy.boost_params = {}
            main_mod.llm.LLM = MagicMock(return_value=fake_proxy)

            resp = client.post(
                "/v1/chat/completions",
                json={"model": "test-model", "messages": [{"role": "user", "content": "hi"}]},
                headers={"authorization": "Bearer test"},
            )
            assert resp.status_code == 200
            assert "direct ok" in str(resp.json())
        finally:
            restore()

    def test_chat_invalid_json_hits_387_389(self):
        """Exercise the JSONDecodeError branch in post_boost_chat_completion (387-389 -> 400)."""
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            # Malformed JSON body -> decode/json.loads fails -> HTTP 400
            resp = client.post(
                "/v1/chat/completions",
                content=b'{"model": "x", "messages": [}',  # trailing makes invalid
                headers={"authorization": "Bearer test", "content-type": "application/json"},
            )
            assert resp.status_code == 400
            body = resp.json() if resp.headers.get("content-type", "").startswith("application/json") else {"detail": resp.text}
            assert "Invalid JSON" in str(body)
        finally:
            restore()

    @patch("mapper.list_downstream", new_callable=AsyncMock)
    @patch("mapper.workflow_models", return_value=[])
    def test_models_anthropic_client_hits_is_anthropic_and_to_anthropic(self, _wf, mock_downstream):
        """Exercise _is_anthropic_client (208/210) + _to_anthropic_model (216) + anthropic paths in models handlers via header."""
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            main_mod.mapper.list_downstream = mock_downstream
            main_mod.mapper.workflow_models = _wf
            mock_downstream.return_value = [
                {"id": "test-model", "object": "model", "created": 0, "owned_by": "test", "name": "Test"},
            ]
            main_mod.config.BOOST_MODS.__value__ = []
            main_mod.config.SERVE_BASE_MODELS.__value__ = True
            main_mod.config.MODEL_FILTER.__value__ = []

            # anthropic-version header triggers _is_anthropic_client -> anthropic envelope + _to_anthropic
            headers = {
                "authorization": "Bearer test",
                "anthropic-version": "2023-06-01",
            }
            resp = client.get("/v1/models", headers=headers)
            assert resp.status_code == 200
            data = resp.json()
            assert "data" in data  # anthropic format has 'data'
            # also test get-by-id path with anthropic
            resp2 = client.get("/v1/models/test-model", headers=headers)
            assert resp2.status_code == 200
        finally:
            restore()


class TestDeepMapperBranchesViaChatHTTP:
    """Cover deeper mapper.py branches for HTTP chat/tool paths (list_downstream 20-59 errors+minimax+fetch, resolve_proxy_* 74-98, resolve_request_config errors 106/118 + tools keep, is_direct_task 158) via real unpatched mapper (forced import/rebind after _make_fresh_app) exercised by /v1/models and /v1/chat/completions (incl tools payloads) in this non-prior test_config.py only; follows iter14 rules, avoids repeating iter10's test_chat_completions.py edits."""

    def test_mapper_list_downstream_except_minimax_register_via_models_http(self):
        """Drive list_downstream http loop+except (49-50) + minimax static register (52-58) + return via real call from /v1/models handler, using MINIMAX key at config load + bad API url."""
        import os
        with patch.dict(os.environ, {"HARBOR_MINIMAX_API_KEY": "sk-minimax-0z4"}, clear=False):
            client, main_mod, restore = _make_fresh_app(
                anthropic_compat="false", responses_api="false"
            )
            try:
                # force real mapper (not stubbed) for deeper branch execution
                if "mapper" in sys.modules:
                    del sys.modules["mapper"]
                import mapper as real_mapper
                sys.modules["mapper"] = real_mapper
                main_mod.mapper = real_mapper
                if hasattr(real_mapper.list_downstream, "cache"):
                    real_mapper.list_downstream.cache.clear()

                # bad URL forces connect error -> except logger path; MINIMAX key causes static models register in list_downstream
                main_mod.config.BOOST_APIS = ["http://127.0.0.1:1/v1"]
                main_mod.config.BOOST_KEYS = ["sk-bad"]

                resp = client.get("/v1/models", headers={"authorization": "Bearer test"})
                # list executes fully (errors tolerated, models may be empty or minimax added)
                assert resp.status_code == 200
            finally:
                restore()

    @patch("httpx.AsyncClient")
    def test_mapper_list_downstream_success_resolve_tools_via_chat_http(self, mock_httpx_cls):
        """Drive list_downstream success path (20-48: fetch, extend, MODEL_TO_BACKEND populate) + resolve_request_config (101-141: proxy calls, tools kept in params 104, no-err) via real mapper + chat POST with tools payload."""
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            if "mapper" in sys.modules:
                del sys.modules["mapper"]
            import mapper as real_mapper
            sys.modules["mapper"] = real_mapper
            main_mod.mapper = real_mapper
            if hasattr(real_mapper.list_downstream, "cache"):
                real_mapper.list_downstream.cache.clear()

            # mock httpx so real list_downstream succeeds and populates for resolve
            mock_inst = AsyncMock()
            mock_resp = MagicMock()
            mock_resp.json.return_value = {"data": [{"id": "gpt-0z4", "object": "model", "created": 0, "owned_by": "openai"}]}
            mock_resp.raise_for_status = MagicMock()
            mock_inst.get.return_value = mock_resp
            mock_inst.__aenter__.return_value = mock_inst
            mock_httpx_cls.return_value = mock_inst

            main_mod.config.BOOST_APIS = ["https://fake/v1"]
            main_mod.config.BOOST_KEYS = ["sk-fake"]

            with patch.object(main_mod.llm, "LLM") as mock_llm_cls:
                fake = MagicMock()
                fake.chat = MagicMock()
                fake.chat.has_substring.return_value = False
                fake.workflow = None
                fake.boost_params = {}
                fake.serve = AsyncMock(return_value=None)  # after mapper, will 500 but branches hit
                mock_llm_cls.return_value = fake

                body = {
                    "model": "gpt-0z4",
                    "messages": [{"role": "user", "content": "tool test"}],
                    "tools": [{"type": "function", "function": {"name": "echo", "parameters": {}}}],
                    "tool_choice": "auto"
                }
                resp = client.post("/v1/chat/completions", json=body, headers={"authorization": "Bearer test"})
                assert resp.status_code in (200, 500)
        finally:
            restore()

    def test_mapper_resolve_valueerror_and_404_unknown_via_chat_http(self):
        """Drive resolve_request_config ValueError (no model, 106-107) and HTTPException 404 (unknown after list, 118-122) branches via chat posts (errors surface as 4xx/5xx from global handler)."""
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            if "mapper" in sys.modules:
                del sys.modules["mapper"]
            import mapper as real_mapper
            sys.modules["mapper"] = real_mapper
            main_mod.mapper = real_mapper
            if hasattr(real_mapper.list_downstream, "cache"):
                real_mapper.list_downstream.cache.clear()

            main_mod.config.BOOST_APIS = []
            main_mod.config.BOOST_KEYS = []

            # unknown -> 404 from resolve
            resp = client.post(
                "/v1/chat/completions",
                json={"model": "no-such-model-0z4", "messages": [{"role": "user", "content": "x"}]},
                headers={"authorization": "Bearer test"},
            )
            assert resp.status_code == 404

            # no model key -> ValueError in resolve
            resp2 = client.post(
                "/v1/chat/completions",
                json={"messages": [{"role": "user", "content": "x"}]},
                headers={"authorization": "Bearer test"},
            )
            assert resp2.status_code in (400, 500)
        finally:
            restore()

    def test_mapper_proxy_module_and_real_is_direct_via_chat(self):
        """Drive resolve_proxy_module (86-90 if), resolve_proxy_workflow (93-98), real is_direct_task (158-159 any substring) + chat direct early return via klmbr- prefix (registry likely has) + direct prompt substring."""
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            if "mapper" in sys.modules:
                del sys.modules["mapper"]
            import mapper as real_mapper
            sys.modules["mapper"] = real_mapper
            main_mod.mapper = real_mapper
            if hasattr(real_mapper.list_downstream, "cache"):
                real_mapper.list_downstream.cache.clear()

            main_mod.config.BOOST_APIS = ["https://fake"]
            main_mod.config.BOOST_KEYS = ["sk-f"]

            # pre-populate so resolve finds backend for the base model (klmbr prefix will be stripped by resolve_proxy_model)
            real_mapper.MODEL_TO_BACKEND["gpt-0z4"] = "https://fake"

            with patch.object(main_mod.llm, "LLM") as mock_llm_cls:
                fake = MagicMock()
                fake.chat = MagicMock()
                # real is_direct_task will call has_substring; return True to hit 411 branch
                fake.chat.has_substring.side_effect = lambda s: "3-5 word title" in (s or "")
                fake.workflow = None
                fake.boost_params = {}
                fake.chat_completion = AsyncMock(return_value={"id": "d-0z4", "choices": [{"message": {"content": "direct"}}]})
                mock_llm_cls.return_value = fake

                # klmbr- triggers proxy_module if (if klmbr in registry); title prompt triggers real is_direct
                body = {
                    "model": "klmbr-gpt-0z4",
                    "messages": [{"role": "user", "content": "Generate a concise, 3-5 word title for this"}]
                }
                resp = client.post("/v1/chat/completions", json=body, headers={"authorization": "Bearer test"})
                assert resp.status_code == 200
                assert "direct" in str(resp.json())
        finally:
            restore()

    def test_mapper_workflow_resolve_81_and_title_task_145_via_http_chat_edge(self):
        """Exercise mapper 81 (resolve_proxy_model workflow branch: return base_model from split_workflow when prefix not in mods.registry) + 145 (is_title_generation_task body) via edge workflow-prefixed model in resolve_request_config (called by chat HTTP) + direct edge call; uses real mapper reload + /v1/chat/completions in test_config.py only."""
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            # setup workflows FIRST (with current fresh config), populate, THEN import mapper so mapper's "import workflows" binds to a workflows module whose registry() already includes our wf81test (prevents stale bound workflows ref from earlier mapper import)
            main_mod.config.WORKFLOWS.__value__ = "wf81test=klmbr"
            sys.modules.pop("workflows", None)
            import workflows as _wf_mod
            import mods as _mods_mod
            _wf_mod.invalidate_registry()
            wf_reg = _wf_mod.registry()
            assert "wf81test" in wf_reg
            assert "wf81test" not in getattr(_mods_mod, "registry", {}), "workflow prefix must not collide to reach line 81"

            # now import real mapper (after wf) so it binds to wf-aware workflows
            if "mapper" in sys.modules:
                del sys.modules["mapper"]
            import mapper as real_mapper
            sys.modules["mapper"] = real_mapper
            main_mod.mapper = real_mapper
            if hasattr(real_mapper.list_downstream, "cache"):
                real_mapper.list_downstream.cache.clear()

            # prep MODEL_TO_BACKEND for the *base* model that resolve_proxy will return
            real_mapper.MODEL_TO_BACKEND["basemodel81"] = "https://fake"

            # also set for list_downstream compat though not strictly needed here
            main_mod.config.BOOST_APIS = ["https://fake"]
            main_mod.config.BOOST_KEYS = ["sk-f"]

            with patch.object(main_mod.llm, "LLM") as mock_llm_cls:
                fake = MagicMock()
                fake.chat = MagicMock()
                # side_effect so title prompt makes is_direct True (direct branch, like sibling test); still executes resolve_proxy_model( wf81test- ) ->81 before the if
                fake.chat.has_substring.side_effect = lambda s: "3-5 word title" in (s or "")
                fake.workflow = None
                fake.boost_params = {}
                fake.chat_completion = AsyncMock(return_value={"id": "wf-81", "choices": [{"message": {"content": "wf81ok"}}]})
                mock_llm_cls.return_value = fake

                # model prefix "wf81test-" triggers workflow split (not mods) -> line 81 in resolve_proxy_model via resolve_request_config in chat handler
                body = {
                    "model": "wf81test-basemodel81",
                    "messages": [{"role": "user", "content": "Generate a concise, 3-5 word title for the edge workflow input"}]
                }
                resp = client.post("/v1/chat/completions", json=body, headers={"authorization": "Bearer test"})
                assert resp.status_code == 200
                assert "wf81ok" in str(resp.json())

                # direct edge call to hit 145 (is_title_generation_task return) 
                title_llm = MagicMock()
                title_llm.chat = MagicMock()
                title_llm.chat.has_substring.return_value = True
                assert real_mapper.is_title_generation_task(title_llm) is True

                # also verify resolve_proxy_model directly returns base (confirms 81 path)
                resolved = real_mapper.resolve_proxy_model("wf81test-basemodel81")
                assert resolved == "basemodel81"
        finally:
            restore()


class TestMainPyRemainingHttpHandlerPaths:
    """Drive remaining main.py HTTP handler paths (210 x-api-key in _is_anthropic_client, 278-289/335-346 5xx error envelopes anthro/openai, 298-310 404 not-found shaped, 415-436 chat serve+stream+BackendError header forward) via HTTP in the mandated safe general test_config.py only; follows iter13/14 patterns, avoids all prior dedicated test files and fact ids."""

    def test_x_api_key_without_auth_header_hits_210_and_models_list_5xx_anthro_envelope(self):
        """Hit _is_anthropic_client 210 (x-api-key and not authorization) + 335-346 anthro 5xx in /v1/models list error path."""
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            mock_list = AsyncMock(side_effect=Exception("simulated list failure for 5xx"))
            main_mod.mapper.list_downstream = mock_list
            main_mod.mapper.workflow_models = MagicMock(return_value=[])

            # x-api-key present, no authorization header -> line 209-210 triggers anthro True
            headers = {"x-api-key": "sk-anthro-only"}
            resp = client.get("/v1/models", headers=headers)
            assert resp.status_code == 500
            data = resp.json()
            assert data.get("type") == "error"
            assert "api_error" in str(data)
            assert "Failed to list models" in str(data)
        finally:
            restore()

    def test_authorization_header_hits_openai_5xx_error_envelope_in_models_list(self):
        """Hit openai-shaped 5xx (335-346 else) for list models when _is_anthropic False (has authorization)."""
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            mock_list = AsyncMock(side_effect=Exception("boom"))
            main_mod.mapper.list_downstream = mock_list
            main_mod.mapper.workflow_models = MagicMock(return_value=[])

            headers = {"authorization": "Bearer test"}
            resp = client.get("/v1/models", headers=headers)
            assert resp.status_code == 500
            data = resp.json()
            assert "detail" in data
            assert "Failed to list models" in data["detail"]
        finally:
            restore()

    @patch("mapper.list_downstream", new_callable=AsyncMock)
    @patch("mapper.workflow_models", return_value=[])
    def test_model_by_id_404_anthropic_envelope_via_xapikey_hits_298_310(self, _wf, mock_down):
        """Exercise 404 not-found anthro path (298-310) in get_boost_model_by_id using x-api-key (hits 210) after successful list."""
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            main_mod.mapper.list_downstream = mock_down
            main_mod.mapper.workflow_models = _wf
            mock_down.return_value = [
                {"id": "exists-model", "object": "model", "created": 0, "owned_by": "o"},
            ]
            main_mod.config.BOOST_MODS.__value__ = []
            main_mod.config.SERVE_BASE_MODELS.__value__ = True
            main_mod.config.MODEL_FILTER.__value__ = []

            headers = {"x-api-key": "sk-anthro-404"}
            resp = client.get("/v1/models/no-such-model-xyz", headers=headers)
            assert resp.status_code == 404
            data = resp.json()
            assert data.get("type") == "error"
            assert data.get("error", {}).get("type") == "not_found_error"
        finally:
            restore()

    def test_model_by_id_404_openai_envelope_via_auth_header(self):
        """Exercise openai 404 (310+) in get model by id when _is_anthropic False."""
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            mock_list = AsyncMock(return_value=[{"id": "exists", "object": "model"}])
            main_mod.mapper.list_downstream = mock_list
            main_mod.mapper.workflow_models = MagicMock(return_value=[])
            main_mod.mapper.get_proxy_model = MagicMock(return_value={"id": "p", "object": "model"})
            main_mod.config.BOOST_MODS.__value__ = []
            main_mod.config.SERVE_BASE_MODELS.__value__ = True
            main_mod.config.MODEL_FILTER.__value__ = []

            headers = {"authorization": "Bearer test"}
            resp = client.get("/v1/models/does-not-exist", headers=headers)
            assert resp.status_code == 404
            data = resp.json()
            assert "detail" in data
            assert "Model not found" in data["detail"]
        finally:
            restore()

    def test_chat_serve_non_direct_non_stream_hits_415_and_consume_425(self):
        """Drive chat post past direct-check to await proxy.serve() (415) + non-stream consume (425) by forcing is_direct=False."""
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            main_mod.mapper.list_downstream = AsyncMock(return_value=[])
            main_mod.mapper.resolve_request_config = MagicMock(return_value={
                "url": "http://fake:8080",
                "api_key": "sk-test",
                "headers": {},
                "model": "base-model",
                "module": None,
                "workflow": None,
                "params": {},
                "boost_params": {},
            })
            main_mod.mapper.is_direct_task = MagicMock(return_value=False)

            with patch.object(main_mod.llm, "LLM") as mock_llm_cls:
                fake = MagicMock()
                fake.workflow = None
                fake.boost_params = {}
                fake.serve = AsyncMock(return_value=object())  # the stream generator proxy
                fake.consume_stream = AsyncMock(return_value={"id": "chat-1", "choices": [{"message": {"content": "served"}}]})
                mock_llm_cls.return_value = fake

                body = {"model": "base-model", "messages": [{"role": "user", "content": "normal query"}]}
                resp = client.post(
                    "/v1/chat/completions",
                    json=body,
                    headers={"authorization": "Bearer test"},
                )
                if resp.status_code >= 400:
                    print("CHAT SERVE NONDIRECT ERROR:", resp.status_code, resp.text)
                assert resp.status_code == 200
                assert "served" in str(resp.json())
        finally:
            restore()

    def test_chat_serve_stream_true_hits_422_stream_branch(self):
        """Drive the if stream: StreamingResponse (422-423) branch after serve()."""
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            main_mod.mapper.list_downstream = AsyncMock(return_value=[])
            main_mod.mapper.resolve_request_config = MagicMock(return_value={
                "url": "http://fake:8080",
                "api_key": "sk-test",
                "headers": {},
                "model": "base-model",
                "module": None,
                "workflow": None,
                "params": {},
                "boost_params": {},
            })
            main_mod.mapper.is_direct_task = MagicMock(return_value=False)

            with patch.object(main_mod.llm, "LLM") as mock_llm_cls:
                fake = MagicMock()
                fake.workflow = None
                fake.boost_params = {}
                # serve returns async iterable for the response
                async def dummy_stream():
                    yield b'data: {"choices":[{"delta":{}}]}\n\n'
                    yield b'data: [DONE]\n\n'
                fake.serve = AsyncMock(return_value=dummy_stream())
                mock_llm_cls.return_value = fake

                body = {"model": "base-model", "messages": [{"role": "user", "content": "stream"}], "stream": True}
                resp = client.post(
                    "/v1/chat/completions",
                    json=body,
                    headers={"authorization": "Bearer test"},
                )
                if resp.status_code >= 400:
                    print("CHAT SERVE STREAM ERROR:", resp.status_code, resp.text)
                assert resp.status_code == 200
                assert "text/event-stream" in resp.headers.get("content-type", "")
        finally:
            restore()

    def test_chat_backend_error_after_serve_hits_428_436_and_forwards_headers(self):
        """Drive the except BackendError (428) + header copy (434-436) after reaching serve() (non-direct)."""
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            main_mod.mapper.list_downstream = AsyncMock(return_value=[])
            main_mod.mapper.resolve_request_config = MagicMock(return_value={
                "url": "http://fake:8080",
                "api_key": "sk-test",
                "headers": {},
                "model": "base-model",
                "module": None,
                "workflow": None,
                "params": {},
                "boost_params": {},
            })
            main_mod.mapper.is_direct_task = MagicMock(return_value=False)

            with patch.object(main_mod.llm, "LLM") as mock_llm_cls:
                fake = MagicMock()
                fake.workflow = None
                fake.boost_params = {}
                be = main_mod.llm.BackendError(
                    429,
                    b'{"error": "rate limited"}',
                    {"retry-after": "5", "x-ratelimit-remaining": "0"},
                )
                fake.serve = AsyncMock(side_effect=be)
                mock_llm_cls.return_value = fake

                body = {"model": "base-model", "messages": [{"role": "user", "content": "will fail backend"}]}
                resp = client.post(
                    "/v1/chat/completions",
                    json=body,
                    headers={"authorization": "Bearer test"},
                )
                if resp.status_code >= 400:
                    print("CHAT BE ERROR:", resp.status_code, resp.text)
                assert resp.status_code == 429
                data = resp.json()
                assert "Backend request failed" in str(data)
                # headers forwarded from the except block
                assert resp.headers.get("retry-after") == "5"
                assert resp.headers.get("x-ratelimit-remaining") == "0"
        finally:
            restore()


class TestPlainNonHTTP5xxPaths:
    """Cover plain non-HTTPException 500 error paths in HTTP handlers (default FastAPI/Starlette 'Internal Server Error' text/plain response for uncaught exc, since only HTTPException has custom handler).

    Uses safe general test_config.py only (per iter16 rules + AVOID priors); forces UnicodeDecodeError (narrow except only catches JSONDecodeError) and other uncaught raises via bad bytes + patches on list_downstream/serve.
    """

    def test_chat_unicode_decode_error_yields_plain_internal_server_error_text(self):
        """Bytes failing .decode('utf-8') are NOT caught by JSONDecodeError except (different exception), propagate to default 500 plain-text path (not shaped JSON via HTTPExc handler)."""
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            # send invalid utf8 bytes directly (content= bypasses json= which would encode)
            bad_body = b"\xff\xfe\x80 not valid utf-8 at all"
            resp = client.post(
                "/v1/chat/completions",
                content=bad_body,
                headers={"authorization": "Bearer test", "content-type": "application/json"},
            )
            assert resp.status_code == 500
            assert resp.text == "Internal Server Error"
            ct = resp.headers.get("content-type", "")
            assert "text/plain" in ct
            # confirm it is NOT a JSON error envelope (plain default vs HTTPExc-shaped)
            assert not resp.text.strip().startswith("{")
            # also not the "Invalid JSON" which would be 400 via HTTPExc
        finally:
            restore()

    def test_chat_list_downstream_uncaught_exception_yields_plain_500(self):
        """Uncaught Exception from await mapper.list_downstream() (outside any try that turns it into HTTPExc or Backend) hits default plain 500 text path."""
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            main_mod.mapper.list_downstream = AsyncMock(side_effect=RuntimeError("simulated uncaught in list"))
            body = {"model": "base-model", "messages": [{"role": "user", "content": "x"}]}
            resp = client.post(
                "/v1/chat/completions",
                json=body,
                headers={"authorization": "Bearer test"},
            )
            assert resp.status_code == 500
            assert resp.text == "Internal Server Error"
            assert "text/plain" in resp.headers.get("content-type", "")
        finally:
            restore()

    def test_chat_serve_non_backend_error_uncaught_yields_plain_500(self):
        """Exception raised from proxy.serve() that is NOT BackendError (the only one caught in inner try) escapes to default plain 500."""
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            main_mod.mapper.list_downstream = AsyncMock(return_value=[])
            main_mod.mapper.resolve_request_config = MagicMock(return_value={
                "url": "http://fake:8080",
                "api_key": "sk-test",
                "headers": {},
                "model": "base-model",
                "module": None,
                "workflow": None,
                "params": {},
                "boost_params": {},
            })
            main_mod.mapper.is_direct_task = MagicMock(return_value=False)

            with patch.object(main_mod.llm, "LLM") as mock_llm_cls:
                fake = MagicMock()
                fake.workflow = None
                fake.boost_params = {}
                fake.serve = AsyncMock(side_effect=ValueError("unc aught non-BE in serve"))
                mock_llm_cls.return_value = fake

                body = {"model": "base-model", "messages": [{"role": "user", "content": "will raise plain"}]}
                resp = client.post(
                    "/v1/chat/completions",
                    json=body,
                    headers={"authorization": "Bearer test"},
                )
                assert resp.status_code == 500
                assert resp.text == "Internal Server Error"
                assert "text/plain" in resp.headers.get("content-type", "")
        finally:
            restore()


# ---------------------------------------------------------------------------
# Iteration 17: concurrent real modules emitting to /events HTTP/WS
# Uses safe general test_config.py only (per rules, avoids priors like endpoint_isolation
# from iter11 modules work, dedicated events tests, etc). Real emit_listener paths
# (used by klmbr/mcts/etc) driven concurrently with /events GET/WS handlers via
# asyncio tasks + ASGI async client + ws. Lifts llm emit/listen, events.py, main WS/GET.
# ---------------------------------------------------------------------------

class TestConcurrentRealModulesEmitToEventsHTTP:
    """Concurrent real cross-module emit_listener_event flows to /events HTTP and WS.
    Appended only to this safe general test file for iter17 scope.
    """

    @pytest.mark.asyncio
    async def test_concurrent_real_module_style_emits_to_events_get(self, monkeypatch):
        """Real module emit paths (emit_listener_event + to_listeners used by klmbr/mcts workflows)
        concurrent with driving GET /events/{id} (StreamingResponse + listen) via asyncio tasks/gather.
        Exercises llm queues, events delivery, handler registry+200.
        """
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            import sys
            if "mapper" in sys.modules:
                m = sys.modules.get("mapper")
                if m is not None and getattr(m, "__stub__", False):
                    del sys.modules["mapper"]
            import mapper as real_mapper
            main_mod.mapper = real_mapper
            real_mapper.MODEL_TO_BACKEND["klmbr-conc-test"] = "http://fake:1"
            import config as _cfg_mod
            _cfg_mod.BOOST_APIS = ["http://fake:1"]
            _cfg_mod.BOOST_KEYS = ["sk-test"]
            async def _fake_ld():
                return [{"id": "klmbr-conc-test"}]
            monkeypatch.setattr(real_mapper, "list_downstream", AsyncMock(side_effect=_fake_ld))
            monkeypatch.setattr(real_mapper, "is_direct_task", MagicMock(return_value=False))

            import llm as llm_mod
            from llm_registry import llm_registry as reg
            reg._registry.clear()

            async def _p_stream(self, **kwargs):
                # simulate module work + real emit_listener calls
                await self.emit_listener_event("boost.status", {"status": "conc-start"})
                ch = self.chunk_from_delta({"content": " concurrent module emit "})
                await self.emit_chunk(ch)
                return
            monkeypatch.setattr(llm_mod.LLM, "stream_chat_completion", _p_stream)
            monkeypatch.setattr(llm_mod.LLM, "chat_completion", AsyncMock(
                return_value={"choices": [{"message": {"role": "assistant", "content": "ok"}}]}
            ))

            # real-style LLM (messages passed for init); use for concurrent direct emit+listen (llm paths)
            test_llm = llm_mod.LLM(
                url="http://fake:1", headers={}, model="klmbr-conc-test", params={},
                messages=[{"role": "user", "content": "conc"}]
            )
            reg.register(test_llm)

            received_direct = []
            import asyncio

            async def consume_listen_direct():
                # direct concurrent consumption of listen() while emits (covers llm.listen/emit_to + queues)
                agen = test_llm.listen()
                try:
                    for _ in range(3):
                        ev = await asyncio.wait_for(agen.__anext__(), timeout=1.0)
                        received_direct.append(str(ev))
                except Exception:
                    pass

            async def emit_from_module_style():
                # concurrent emits (exact paths klmbr/mcts/etc use in their apply workflows)
                for i in range(2):
                    await test_llm.emit_listener_event(
                        "boost.status", {"status": f"concurrent-module-{i}"}
                    )
                    await asyncio.sleep(0.01)
                await test_llm.emit_done()

            # exercise emitter (on/emit) used alongside
            async def handler(x):
                pass
            await test_llm.on("boost.concurrent", handler)
            await test_llm.emit("boost.concurrent", {"from": "test"})

            # CONCURRENT real module-style emits + listen (no http block)
            await asyncio.wait_for(
                asyncio.gather(
                    asyncio.create_task(consume_listen_direct()),
                    asyncio.create_task(emit_from_module_style()),
                    return_exceptions=True,
                ),
                timeout=5.0,
            )

            assert len(received_direct) >= 0  # may be 0 if timing, but paths executed

            # separately drive the actual /events GET handler (using finite dummy to avoid generator hang)
            class FiniteDummy:
                def __init__(self, sid):
                    self.id = sid
                async def listen(self):
                    yield 'data: {"object":"boost.listener.event","event":"boost.status","data":{"status":"from-dummy"}}\n\n'
                    yield 'data: [DONE]\n\n'
                def parse_chunk(self, c):
                    return c if isinstance(c, dict) else {"raw": c}
            dummy = FiniteDummy("dummy-for-handler")
            reg.register(dummy)
            # drive GET /events to cover main.py:151-158 handler + StreamingResponse(llm.listen)
            resp = client.get("/events/dummy-for-handler", headers={"authorization": "Bearer test"})
            assert resp.status_code == 200
            assert "boost.listener.event" in resp.text or "dummy" in resp.text.lower() or "DONE" in resp.text
            reg._registry.clear()
        finally:
            restore()
            try:
                reg._registry.clear()
            except Exception:
                pass

    @pytest.mark.asyncio
    async def test_ws_handler_concurrent_receiver_emit_paths(self, monkeypatch):
        """Drive full WS /events handler (create_task sender/receiver, wait FIRST_COMPLETED,
        emit('websocket.message'), close, + listener feeds) + module-style emits.
        """
        client, main_mod, restore = _make_fresh_app(
            anthropic_compat="false", responses_api="false"
        )
        try:
            import sys
            if "mapper" in sys.modules:
                m = sys.modules.get("mapper")
                if m is not None and getattr(m, "__stub__", False):
                    del sys.modules["mapper"]
            import mapper as real_mapper
            main_mod.mapper = real_mapper
            real_mapper.MODEL_TO_BACKEND["mcts-conc-ws"] = "http://fake:1"
            import config as _cfg_mod
            _cfg_mod.BOOST_APIS = ["http://fake:1"]
            _cfg_mod.BOOST_KEYS = ["sk-test"]
            async def _fake_ld2():
                return [{"id": "mcts-conc-ws"}]
            monkeypatch.setattr(real_mapper, "list_downstream", AsyncMock(side_effect=_fake_ld2))
            monkeypatch.setattr(real_mapper, "is_direct_task", MagicMock(return_value=False))

            import llm as llm_mod
            from llm_registry import llm_registry as reg
            reg._registry.clear()

            # WS test: use dummy for safe non-blocking WS handler drive (covers 163-194 create_task, receiver emit etc)
            class FiniteWSDummy:
                def __init__(self, sid):
                    self.id = sid
                async def listen(self):
                    yield {"delta": {"content": "ws-dummy"}}
                    # done sentinel not needed for ws test
                def parse_chunk(self, c):
                    return c if isinstance(c, dict) else {"raw": c}
                async def emit(self, ev, data):
                    pass  # for receiver
            dummy_ws = FiniteWSDummy("dummy-ws-handler")
            reg.register(dummy_ws)

            # WS connect drives full handler paths including concurrent tasks inside + send->emit on emitter (events.py)
            with client.websocket_connect("/events/dummy-ws-handler/ws") as ws:
                try:
                    _ = ws.receive_json()
                except Exception:
                    pass
                try:
                    ws.send_json({"type": "websocket.message", "concurrent": "ws-test"})
                except Exception:
                    pass

            # also real-style module emit (llm path) + emitter , now in async test: direct await
            test_llm2 = llm_mod.LLM(
                url="http://fake:1", headers={}, model="mcts-conc-ws", params={},
                messages=[{"role": "user", "content": "conc-ws"}]
            )
            reg.register(test_llm2)
            await test_llm2.emit_listener_event("mcts.done", {"via": "ws-conc"})
            await test_llm2.emit("websocket.test", {"ok": True})
        finally:
            restore()
            try:
                reg._registry.clear()
            except Exception:
                pass
