"""
Plan review workflow tests across providers.

Tests the plan_review consultation workflow with each provider to verify:
1. Provider can process a plan review prompt
2. Response contains expected structure (feasibility, issues, recommendation)
3. Response is parseable JSON

NOTE: These tests validate response STRUCTURE only, not semantic AI correctness.
We do not assert whether the AI's plan review judgment is correct.

Run with: pytest tests/integration/providers/test_plan_review_flow.py -m plan_review
Enable live tests: FOUNDRY_ENABLE_LIVE_PROVIDER_TESTS=1
"""

import pytest

from foundry_mcp.core.providers import (
    ProviderHooks,
    resolve_provider,
)


# =============================================================================
# Per-Provider Plan Review Tests (Structure Validation Only)
# =============================================================================


@pytest.mark.plan_review
@pytest.mark.live_providers
@pytest.mark.gemini
class TestGeminiPlanReview:
    """Plan review structure tests for Gemini provider."""

    def test_plan_review_response_structure(
        self,
        simple_plan_review_prompt,
        provider_request_factory,
        validate_provider_result,
        validate_json_response,
    ):
        """Test gemini returns valid plan review response structure."""
        provider = resolve_provider("gemini", hooks=ProviderHooks())
        request = provider_request_factory(
            simple_plan_review_prompt,
            timeout=60.0,
            temperature=0.3,
        )

        result = provider.generate(request)

        validated = validate_provider_result(result)
        data = validate_json_response(
            validated.content,
            required_keys=["feasibility", "recommendation"],
        )

        # Structure validation only - no semantic correctness assertions
        assert isinstance(data["feasibility"], str), "feasibility must be string"
        assert isinstance(data["recommendation"], str), "recommendation must be string"
        assert isinstance(data.get("issues", []), list), "issues must be list"


@pytest.mark.plan_review
@pytest.mark.live_providers
@pytest.mark.codex
class TestCodexPlanReview:
    """Plan review structure tests for Codex provider."""

    def test_plan_review_response_structure(
        self,
        simple_plan_review_prompt,
        provider_request_factory,
        validate_provider_result,
        validate_json_response,
    ):
        """Test codex returns valid plan review response structure."""
        provider = resolve_provider("codex", hooks=ProviderHooks())
        request = provider_request_factory(
            simple_plan_review_prompt,
            timeout=60.0,
            temperature=0.3,
        )

        result = provider.generate(request)

        validated = validate_provider_result(result)
        data = validate_json_response(
            validated.content,
            required_keys=["feasibility", "recommendation"],
        )

        assert isinstance(data["feasibility"], str), "feasibility must be string"
        assert isinstance(data["recommendation"], str), "recommendation must be string"
        assert isinstance(data.get("issues", []), list), "issues must be list"


@pytest.mark.plan_review
@pytest.mark.live_providers
@pytest.mark.claude
class TestClaudePlanReview:
    """Plan review structure tests for Claude provider."""

    def test_plan_review_response_structure(
        self,
        simple_plan_review_prompt,
        provider_request_factory,
        validate_provider_result,
        validate_json_response,
    ):
        """Test claude returns valid plan review response structure."""
        provider = resolve_provider("claude", hooks=ProviderHooks())
        request = provider_request_factory(
            simple_plan_review_prompt,
            model="haiku",
            timeout=60.0,
            temperature=0.3,
        )

        result = provider.generate(request)

        validated = validate_provider_result(result)
        data = validate_json_response(
            validated.content,
            required_keys=["feasibility", "recommendation"],
        )

        assert isinstance(data["feasibility"], str), "feasibility must be string"
        assert isinstance(data["recommendation"], str), "recommendation must be string"
        assert isinstance(data.get("issues", []), list), "issues must be list"


@pytest.mark.plan_review
@pytest.mark.live_providers
@pytest.mark.cursor_agent
class TestCursorAgentPlanReview:
    """Plan review structure tests for Cursor Agent provider."""

    def test_plan_review_response_structure(
        self,
        simple_plan_review_prompt,
        provider_request_factory,
        validate_provider_result,
        validate_json_response,
    ):
        """Test cursor-agent returns valid plan review response structure."""
        provider = resolve_provider("cursor-agent", hooks=ProviderHooks())
        request = provider_request_factory(
            simple_plan_review_prompt,
            timeout=60.0,
            temperature=0.3,
        )

        result = provider.generate(request)

        validated = validate_provider_result(result)
        data = validate_json_response(
            validated.content,
            required_keys=["feasibility", "recommendation"],
        )

        assert isinstance(data["feasibility"], str), "feasibility must be string"
        assert isinstance(data["recommendation"], str), "recommendation must be string"
        assert isinstance(data.get("issues", []), list), "issues must be list"


@pytest.mark.plan_review
@pytest.mark.live_providers
@pytest.mark.opencode
class TestOpenCodePlanReview:
    """Plan review structure tests for OpenCode provider."""

    def test_plan_review_response_structure(
        self,
        simple_plan_review_prompt,
        provider_request_factory,
        validate_provider_result,
        validate_json_response,
    ):
        """Test opencode returns valid plan review response structure."""
        provider = resolve_provider("opencode", hooks=ProviderHooks())
        request = provider_request_factory(
            simple_plan_review_prompt,
            timeout=60.0,
            temperature=0.3,
        )

        result = provider.generate(request)

        validated = validate_provider_result(result)
        data = validate_json_response(
            validated.content,
            required_keys=["feasibility", "recommendation"],
        )

        assert isinstance(data["feasibility"], str), "feasibility must be string"
        assert isinstance(data["recommendation"], str), "recommendation must be string"
        assert isinstance(data.get("issues", []), list), "issues must be list"


# =============================================================================
# Cross-Provider Plan Review Comparison
# =============================================================================


@pytest.mark.plan_review
@pytest.mark.live_providers
@pytest.mark.slow
class TestCrossProviderPlanReview:
    """Compare plan review response structure across providers."""

    def test_all_providers_return_valid_structure(
        self,
        simple_plan_review_prompt,
        available_providers_list,
        provider_request_factory,
        validate_provider_result,
        validate_json_response,
    ):
        """Test all providers return valid plan review response structure."""
        if not available_providers_list:
            pytest.skip("No providers available")

        results = {}
        failures = {}

        for provider_id in available_providers_list:
            try:
                provider = resolve_provider(provider_id, hooks=ProviderHooks())
                request = provider_request_factory(
                    simple_plan_review_prompt,
                    timeout=60.0,
                    temperature=0.3,
                )
                result = provider.generate(request)
                validated = validate_provider_result(result)
                data = validate_json_response(
                    validated.content,
                    required_keys=["feasibility", "recommendation"],
                )
                results[provider_id] = data
            except Exception as e:
                failures[provider_id] = str(e)

        # Report results
        print(f"\nPlan Review Structure Results:")
        for provider_id, data in results.items():
            feasibility_type = type(data["feasibility"]).__name__
            recommendation_type = type(data["recommendation"]).__name__
            issues_count = len(data.get("issues", []))
            print(f"  {provider_id}: feasibility={feasibility_type}, recommendation={recommendation_type}, issues={issues_count}")

        if failures:
            print(f"\nProvider Failures:")
            for provider_id, error in failures.items():
                print(f"  {provider_id}: {error}")

        # Validate structure for all successful responses
        for provider_id, data in results.items():
            assert isinstance(data["feasibility"], str), f"{provider_id}: feasibility must be string"
            assert isinstance(data["recommendation"], str), f"{provider_id}: recommendation must be string"
            assert isinstance(data.get("issues", []), list), f"{provider_id}: issues must be list"

        # At least one provider should succeed
        assert results, f"All providers failed: {failures}"
