"""Optimizer 回归保护测试。"""

from unittest.mock import patch

from promptgrad.models import ExecutionResult, TestCase
from promptgrad.optimizer import Optimizer


class TestRegressionCheck:
    @patch("promptgrad.optimizer.Executor")
    def test_regression_pass(self, MockExecutor):
        """新 prompt 在已通过 case 上通过率不下降 -> 通过。"""
        mock_executor = MockExecutor.return_value
        mock_executor.run.return_value = [
            ExecutionResult(case_id="c1", input={"q": "a"}, output="good", latency_ms=100, token_usage={}),
            ExecutionResult(case_id="c2", input={"q": "b"}, output="good", latency_ms=100, token_usage={}),
        ]

        optimizer = Optimizer(concurrency=2)
        passed_cases = [
            TestCase(id="c1", input={"q": "a"}, golden="good", tags=[]),
            TestCase(id="c2", input={"q": "b"}, golden="good", tags=[]),
        ]
        rubric = {
            "dimensions": [{"name": "acc", "weight": 1.0, "eval_method": "reference", "metric": "exact_match"}],
            "pass_threshold": 0.8,
        }
        result = optimizer.regression_check(
            new_prompt={"system": "new", "template": "{{q}}", "few_shot_examples": []},
            passed_cases=passed_cases,
            model_config={"name": "m", "temperature": 0, "max_tokens": 100},
            rubric=rubric,
            prev_pass_rate=1.0,
        )
        assert result is True

    @patch("promptgrad.optimizer.Executor")
    def test_regression_fail(self, MockExecutor):
        """新 prompt 在已通过 case 上通过率下降 -> 拒绝。"""
        mock_executor = MockExecutor.return_value
        mock_executor.run.return_value = [
            ExecutionResult(case_id="c1", input={"q": "a"}, output="bad output", latency_ms=100, token_usage={}),
            ExecutionResult(case_id="c2", input={"q": "b"}, output="bad output", latency_ms=100, token_usage={}),
        ]

        optimizer = Optimizer(concurrency=2)
        passed_cases = [
            TestCase(id="c1", input={"q": "a"}, golden="good", tags=[]),
            TestCase(id="c2", input={"q": "b"}, golden="good", tags=[]),
        ]
        rubric = {
            "dimensions": [{"name": "acc", "weight": 1.0, "eval_method": "reference", "metric": "exact_match"}],
            "pass_threshold": 0.8,
        }
        result = optimizer.regression_check(
            new_prompt={"system": "new", "template": "{{q}}", "few_shot_examples": []},
            passed_cases=passed_cases,
            model_config={"name": "m", "temperature": 0, "max_tokens": 100},
            rubric=rubric,
            prev_pass_rate=1.0,
        )
        assert result is False

    def test_regression_no_passed_cases(self):
        """无已通过 case 时直接通过。"""
        optimizer = Optimizer(concurrency=2)
        result = optimizer.regression_check(
            new_prompt={"system": "new", "template": "{{q}}", "few_shot_examples": []},
            passed_cases=[],
            model_config={"name": "m", "temperature": 0, "max_tokens": 100},
            rubric={"dimensions": [], "pass_threshold": 0.8},
            prev_pass_rate=0.0,
        )
        assert result is True
