"""Tests for ForcedContinuationService."""

import pytest

from src.forced_continuation import ForcedContinuationService
from src.gates.quality_gate import GateResult
from src.quality_orchestrator import VerificationResult


class TestForcedContinuationService:
    """Test suite for ForcedContinuationService."""

    @pytest.fixture
    def service(self) -> ForcedContinuationService:
        """Create a ForcedContinuationService instance for testing."""
        return ForcedContinuationService()

    def test_generate_prompt_single_build_failure(
        self, service: ForcedContinuationService
    ) -> None:
        """Test prompt generation for single build gate failure."""
        verification = VerificationResult(
            all_passed=False,
            gate_results={
                "build": GateResult(
                    passed=False,
                    message="Build gate failed: Type errors detected",
                    details={
                        "return_code": 1,
                        "stderr": "src/main.py:10: error: Incompatible return value type",
                    },
                ),
                "lint": GateResult(passed=True, message="Lint passed", details={}),
                "test": GateResult(passed=True, message="Test passed", details={}),
                "coverage": GateResult(
                    passed=True, message="Coverage passed", details={}
                ),
            },
        )

        prompt = service.generate_prompt(verification)

        # Assert prompt structure
        assert isinstance(prompt, str)
        assert len(prompt) > 0
        assert "build" in prompt.lower() or "type" in prompt.lower()
        assert "failed" in prompt.lower() or "error" in prompt.lower()
        # Should be non-negotiable and directive
        assert (
            "must" in prompt.lower()
            or "required" in prompt.lower()
            or "fix" in prompt.lower()
        )

    def test_generate_prompt_single_lint_failure(
        self, service: ForcedContinuationService
    ) -> None:
        """Test prompt generation for single lint gate failure."""
        verification = VerificationResult(
            all_passed=False,
            gate_results={
                "build": GateResult(passed=True, message="Build passed", details={}),
                "lint": GateResult(
                    passed=False,
                    message="Lint gate failed: Linting issues detected",
                    details={
                        "return_code": 1,
                        "stderr": (
                            "src/main.py:10: E501 line too long\n"
                            "src/models.py:5: F401 unused import"
                        ),
                    },
                ),
                "test": GateResult(passed=True, message="Test passed", details={}),
                "coverage": GateResult(
                    passed=True, message="Coverage passed", details={}
                ),
            },
        )

        prompt = service.generate_prompt(verification)

        # Assert prompt structure
        assert isinstance(prompt, str)
        assert len(prompt) > 0
        assert "lint" in prompt.lower()
        assert "failed" in prompt.lower() or "error" in prompt.lower()
        assert (
            "must" in prompt.lower()
            or "required" in prompt.lower()
            or "fix" in prompt.lower()
        )

    def test_generate_prompt_single_test_failure(
        self, service: ForcedContinuationService
    ) -> None:
        """Test prompt generation for single test gate failure."""
        verification = VerificationResult(
            all_passed=False,
            gate_results={
                "build": GateResult(passed=True, message="Build passed", details={}),
                "lint": GateResult(passed=True, message="Lint passed", details={}),
                "test": GateResult(
                    passed=False,
                    message="Test gate failed: Test failures detected",
                    details={
                        "return_code": 1,
                        "stderr": "FAILED tests/test_main.py::test_function - AssertionError",
                    },
                ),
                "coverage": GateResult(
                    passed=True, message="Coverage passed", details={}
                ),
            },
        )

        prompt = service.generate_prompt(verification)

        # Assert prompt structure
        assert isinstance(prompt, str)
        assert len(prompt) > 0
        assert "test" in prompt.lower()
        assert "failed" in prompt.lower() or "error" in prompt.lower()
        assert (
            "must" in prompt.lower()
            or "required" in prompt.lower()
            or "fix" in prompt.lower()
        )

    def test_generate_prompt_single_coverage_failure(
        self, service: ForcedContinuationService
    ) -> None:
        """Test prompt generation for single coverage gate failure."""
        verification = VerificationResult(
            all_passed=False,
            gate_results={
                "build": GateResult(passed=True, message="Build passed", details={}),
                "lint": GateResult(passed=True, message="Lint passed", details={}),
                "test": GateResult(passed=True, message="Test passed", details={}),
                "coverage": GateResult(
                    passed=False,
                    message="Coverage gate failed: 75.0% coverage below minimum 85%",
                    details={
                        "coverage_percent": 75.0,
                        "minimum_coverage": 85.0,
                    },
                ),
            },
        )

        prompt = service.generate_prompt(verification)

        # Assert prompt structure
        assert isinstance(prompt, str)
        assert len(prompt) > 0
        assert "coverage" in prompt.lower()
        assert "75" in prompt or "85" in prompt  # Should include actual/minimum coverage
        assert (
            "must" in prompt.lower()
            or "required" in prompt.lower()
            or "fix" in prompt.lower()
        )

    def test_generate_prompt_multiple_failures(
        self, service: ForcedContinuationService
    ) -> None:
        """Test prompt generation for multiple gate failures."""
        verification = VerificationResult(
            all_passed=False,
            gate_results={
                "build": GateResult(
                    passed=False,
                    message="Build gate failed: Type errors detected",
                    details={
                        "return_code": 1,
                        "stderr": "src/main.py:10: error: Incompatible return value type",
                    },
                ),
                "lint": GateResult(
                    passed=False,
                    message="Lint gate failed: Linting issues detected",
                    details={
                        "return_code": 1,
                        "stderr": "src/main.py:10: E501 line too long",
                    },
                ),
                "test": GateResult(passed=True, message="Test passed", details={}),
                "coverage": GateResult(
                    passed=False,
                    message="Coverage gate failed: 75.0% coverage below minimum 85%",
                    details={
                        "coverage_percent": 75.0,
                        "minimum_coverage": 85.0,
                    },
                ),
            },
        )

        prompt = service.generate_prompt(verification)

        # Assert prompt structure
        assert isinstance(prompt, str)
        assert len(prompt) > 0
        # Should mention multiple failures
        assert "build" in prompt.lower() or "type" in prompt.lower()
        assert "lint" in prompt.lower()
        assert "coverage" in prompt.lower()
        # Should be non-negotiable
        assert (
            "must" in prompt.lower()
            or "required" in prompt.lower()
            or "fix" in prompt.lower()
        )

    def test_generate_prompt_all_failures(
        self, service: ForcedContinuationService
    ) -> None:
        """Test prompt generation when all gates fail."""
        verification = VerificationResult(
            all_passed=False,
            gate_results={
                "build": GateResult(
                    passed=False,
                    message="Build gate failed",
                    details={},
                ),
                "lint": GateResult(
                    passed=False,
                    message="Lint gate failed",
                    details={},
                ),
                "test": GateResult(
                    passed=False,
                    message="Test gate failed",
                    details={},
                ),
                "coverage": GateResult(
                    passed=False,
                    message="Coverage gate failed",
                    details={},
                ),
            },
        )

        prompt = service.generate_prompt(verification)

        # Assert prompt structure
        assert isinstance(prompt, str)
        assert len(prompt) > 0
        # Should mention all gates
        assert "build" in prompt.lower() or "type" in prompt.lower()
        assert "lint" in prompt.lower()
        assert "test" in prompt.lower()
        assert "coverage" in prompt.lower()
        # Should be strongly worded
        assert (
            "must" in prompt.lower()
            or "required" in prompt.lower()
            or "fix" in prompt.lower()
        )

    def test_generate_prompt_includes_actionable_details(
        self, service: ForcedContinuationService
    ) -> None:
        """Test that generated prompt includes actionable details from gate results."""
        verification = VerificationResult(
            all_passed=False,
            gate_results={
                "build": GateResult(
                    passed=False,
                    message="Build gate failed: Type errors detected",
                    details={
                        "return_code": 1,
                        "stderr": "src/main.py:10: error: Incompatible return value type\n"
                        "src/models.py:5: error: Missing type annotation",
                    },
                ),
                "lint": GateResult(passed=True, message="Lint passed", details={}),
                "test": GateResult(passed=True, message="Test passed", details={}),
                "coverage": GateResult(
                    passed=True, message="Coverage passed", details={}
                ),
            },
        )

        prompt = service.generate_prompt(verification)

        # Assert prompt includes specific error details
        assert isinstance(prompt, str)
        assert len(prompt) > 0
        # Should include file references or specific errors when available
        assert (
            "main.py" in prompt
            or "models.py" in prompt
            or "error" in prompt.lower()
        )

    def test_generate_prompt_clear_instructions(
        self, service: ForcedContinuationService
    ) -> None:
        """Test that generated prompt provides clear instructions."""
        verification = VerificationResult(
            all_passed=False,
            gate_results={
                "build": GateResult(passed=True, message="Build passed", details={}),
                "lint": GateResult(passed=True, message="Lint passed", details={}),
                "test": GateResult(
                    passed=False,
                    message="Test gate failed: Test failures detected",
                    details={
                        "return_code": 1,
                    },
                ),
                "coverage": GateResult(
                    passed=True, message="Coverage passed", details={}
                ),
            },
        )

        prompt = service.generate_prompt(verification)

        # Assert prompt has clear instructions
        assert isinstance(prompt, str)
        assert len(prompt) > 50  # Should be substantial, not just a one-liner
        # Should tell agent what to do, not just what failed
        assert "fix" in prompt.lower() or "resolve" in prompt.lower()

    def test_generate_prompt_raises_on_all_passed(
        self, service: ForcedContinuationService
    ) -> None:
        """Test that generate_prompt raises error when all gates pass."""
        verification = VerificationResult(
            all_passed=True,
            gate_results={
                "build": GateResult(passed=True, message="Build passed", details={}),
                "lint": GateResult(passed=True, message="Lint passed", details={}),
                "test": GateResult(passed=True, message="Test passed", details={}),
                "coverage": GateResult(
                    passed=True, message="Coverage passed", details={}
                ),
            },
        )

        # Should raise ValueError or similar when trying to generate prompt for passing verification
        with pytest.raises(ValueError, match="all.*pass"):
            service.generate_prompt(verification)
