# #region TestAdaptiveBatchSizer [C:3] [TYPE Module] [SEMANTICS test, batch, sizer, provider, config]
# @BRIEF Verify AdaptiveBatchSizer contracts — provider config resolution, safety factor, row cap.
# @RELATION BINDS_TO -> [AdaptiveBatchSizer]
# @TEST_EDGE  resolve_provider_config_no_provider — no provider_id returns all-None
# @TEST_EDGE  resolve_provider_config_with_provider — returns model + token limits from DB
# @TEST_EDGE  resolve_provider_config_exception — DB error returns all-None gracefully

from unittest.mock import MagicMock, patch

from src.models.translate import TranslationJob
from src.plugins.translate._batch_sizer import AdaptiveBatchSizer


# region TestResolveProviderConfig [TYPE Class]
# @BRIEF Tests for AdaptiveBatchSizer.resolve_provider_config.
class TestResolveProviderConfig:

    # region test_no_provider_id [TYPE Function]
    # @BRIEF When job has no provider_id, returns all-None dict.
    def test_no_provider_id(self):
        job = MagicMock(spec=TranslationJob)
        job.provider_id = None
        sizer = AdaptiveBatchSizer(db=MagicMock(), config_manager=MagicMock())
        result = sizer.resolve_provider_config(job)
        assert result == {"model": None, "context_window": None, "max_output_tokens": None}
    # endregion test_no_provider_id

    # region test_with_provider_full_config [TYPE Function]
    # @BRIEF Provider with context_window and max_output_tokens returns all values.
    @patch("src.plugins.translate._batch_sizer.LLMProviderService")
    def test_with_provider_full_config(self, mock_provider_svc):
        job = MagicMock(spec=TranslationJob)
        job.provider_id = "provider-1"

        mock_svc_instance = MagicMock()
        mock_svc_instance.get_provider_token_config.return_value = {
            "model": "gpt-4o-mini",
            "context_window": 128000,
            "max_output_tokens": 16384,
        }
        mock_provider_svc.return_value = mock_svc_instance

        sizer = AdaptiveBatchSizer(db=MagicMock(), config_manager=MagicMock())
        result = sizer.resolve_provider_config(job)
        assert result["model"] == "gpt-4o-mini"
        assert result["context_window"] == 128000
        assert result["max_output_tokens"] == 16384
    # endregion test_with_provider_full_config

    # region test_with_provider_null_config [TYPE Function]
    # @BRIEF Provider with NULL token limits still returns model + None values.
    @patch("src.plugins.translate._batch_sizer.LLMProviderService")
    def test_with_provider_null_config(self, mock_provider_svc):
        job = MagicMock(spec=TranslationJob)
        job.provider_id = "provider-2"

        mock_svc_instance = MagicMock()
        mock_svc_instance.get_provider_token_config.return_value = {
            "model": "deepseek-v4-flash",
            "context_window": None,
            "max_output_tokens": None,
        }
        mock_provider_svc.return_value = mock_svc_instance

        sizer = AdaptiveBatchSizer(db=MagicMock(), config_manager=MagicMock())
        result = sizer.resolve_provider_config(job)
        assert result["model"] == "deepseek-v4-flash"
        assert result["context_window"] is None  # NULL → use PROVIDER_DEFAULTS
        assert result["max_output_tokens"] is None
    # endregion test_with_provider_null_config

    # region test_exception_returns_safe_defaults [TYPE Function]
    # @BRIEF DB exception returns all-None dict gracefully.
    @patch("src.plugins.translate._batch_sizer.LLMProviderService")
    def test_exception_returns_safe_defaults(self, mock_provider_svc):
        job = MagicMock(spec=TranslationJob)
        job.provider_id = "provider-3"

        mock_svc_instance = MagicMock()
        mock_svc_instance.get_provider_token_config.side_effect = Exception("DB error")
        mock_provider_svc.return_value = mock_svc_instance

        sizer = AdaptiveBatchSizer(db=MagicMock(), config_manager=MagicMock())
        result = sizer.resolve_provider_config(job)
        assert result == {"model": None, "context_window": None, "max_output_tokens": None}
    # endregion test_exception_returns_safe_defaults

# endregion TestResolveProviderConfig
# #endregion TestAdaptiveBatchSizer
