"""Tests for bicep_whatif_advisor.prompt module."""

import pytest

from bicep_whatif_advisor.prompt import build_system_prompt, build_user_prompt


@pytest.mark.unit
class TestBuildSystemPrompt:
    def test_standard_mode_returns_string(self):
        result = build_system_prompt()
        assert isinstance(result, str)
        assert len(result) > 0

    def test_standard_mode_contains_json_schema(self):
        result = build_system_prompt()
        assert "resource_name" in result
        assert "resource_type" in result
        assert "action" in result
        assert "confidence_level" in result

    def test_standard_mode_verbose_includes_changes(self):
        result = build_system_prompt(verbose=True)
        assert "changes" in result.lower()

    def test_standard_mode_non_verbose_no_changes_field(self):
        result = build_system_prompt(verbose=False)
        assert 'also include a "changes" field' not in result

    def test_ci_mode_includes_risk_assessment(self):
        result = build_system_prompt(ci_mode=True)
        assert "risk_assessment" in result
        assert "verdict" in result

    def test_ci_mode_includes_drift(self):
        result = build_system_prompt(ci_mode=True, enabled_buckets=["drift"])
        assert "Infrastructure Drift" in result

    def test_ci_mode_no_intent_without_pr(self):
        result = build_system_prompt(ci_mode=True, pr_title=None)
        assert "PR Intent Alignment" not in result

    def test_ci_mode_with_intent_when_pr_title(self):
        result = build_system_prompt(ci_mode=True, pr_title="Add storage")
        assert "PR Intent Alignment" in result
        assert "intent" in result

    def test_ci_mode_with_intent_when_pr_description(self):
        result = build_system_prompt(ci_mode=True, pr_description="Some desc")
        assert "PR Intent Alignment" in result

    def test_ci_mode_custom_enabled_buckets(self):
        """Custom agent buckets are included when specified."""
        from bicep_whatif_advisor.ci.buckets import RISK_BUCKETS, RiskBucket

        RISK_BUCKETS["compliance"] = RiskBucket(
            id="compliance",
            display_name="Compliance Review",
            description="Custom agent",
            prompt_instructions="Check compliance.",
            custom=True,
        )
        try:
            result = build_system_prompt(ci_mode=True, enabled_buckets=["compliance"])
            assert "Compliance Review" in result
            assert "Infrastructure Drift" not in result
        finally:
            del RISK_BUCKETS["compliance"]

    def test_ci_mode_schema_has_risk_level(self):
        result = build_system_prompt(ci_mode=True)
        assert "risk_level" in result
        assert "risk_reason" in result

    def test_confidence_section_always_present(self):
        for mode in [False, True]:
            result = build_system_prompt(ci_mode=mode)
            assert "Confidence Assessment" in result

    def test_ci_mode_dynamic_bucket_count(self):
        result = build_system_prompt(
            ci_mode=True, enabled_buckets=["drift", "intent"], pr_title="Test"
        )
        assert "2 independent risk buckets" in result

    def test_ci_mode_single_bucket_wording(self):
        result = build_system_prompt(ci_mode=True, enabled_buckets=["drift"])
        assert "1 independent risk bucket:" in result

    def test_custom_agent_table_display_has_findings_in_schema(self):
        from bicep_whatif_advisor.ci.buckets import RISK_BUCKETS, RiskBucket

        RISK_BUCKETS["naming"] = RiskBucket(
            id="naming",
            display_name="Naming Convention",
            description="Custom agent",
            prompt_instructions="Check naming.",
            custom=True,
            display="table",
            icon="\U0001f4db",
        )
        try:
            result = build_system_prompt(ci_mode=True, enabled_buckets=["drift", "naming"])
            # The naming bucket should have a findings array in the schema
            assert '"findings"' in result
            assert '"resource"' in result
            assert '"issue"' in result
            assert '"recommendation"' in result
            # And the findings instructions should be present
            assert 'populate the "findings" array' in result
        finally:
            del RISK_BUCKETS["naming"]

    def test_custom_columns_in_schema(self):
        """Custom columns replace default resource/issue/recommendation in schema."""
        from bicep_whatif_advisor.ci.buckets import RISK_BUCKETS, RiskBucket

        RISK_BUCKETS["sfi"] = RiskBucket(
            id="sfi",
            display_name="Secure Infrastructure",
            description="Custom agent",
            prompt_instructions="Check SFI.",
            custom=True,
            display="table",
            columns=[
                {
                    "name": "SFI ID and Name",
                    "key": "sfi_id_and_name",
                    "description": "from check title",
                },
                {
                    "name": "Compliance Status",
                    "key": "compliance_status",
                    "description": "compliant or not",
                },
                {
                    "name": "Applicable",
                    "key": "applicable",
                    "description": "true/false",
                },
            ],
        )
        try:
            result = build_system_prompt(ci_mode=True, enabled_buckets=["sfi"])
            # Custom column keys should appear
            assert '"sfi_id_and_name"' in result
            assert '"compliance_status"' in result
            assert '"applicable"' in result
            # Default columns should NOT appear
            assert '"resource": "string' not in result
            assert '"issue": "string' not in result
            assert '"recommendation": "string' not in result
            # Instructions should reference custom column keys
            assert '"sfi_id_and_name" (from check title)' in result
            assert '"compliance_status" (compliant or not)' in result
        finally:
            del RISK_BUCKETS["sfi"]

    def test_builtin_bucket_no_findings_in_schema(self):
        """Built-in buckets (drift) don't get findings in the schema."""
        result = build_system_prompt(ci_mode=True, enabled_buckets=["drift"])
        assert '"findings"' not in result

    def test_summary_display_no_findings_in_schema(self):
        """Summary-display custom agents don't get findings in the schema."""
        from bicep_whatif_advisor.ci.buckets import RISK_BUCKETS, RiskBucket

        RISK_BUCKETS["cost"] = RiskBucket(
            id="cost",
            display_name="Cost Impact",
            description="Custom agent",
            prompt_instructions="Check cost.",
            custom=True,
            display="summary",
        )
        try:
            result = build_system_prompt(ci_mode=True, enabled_buckets=["drift", "cost"])
            assert '"findings"' not in result
        finally:
            del RISK_BUCKETS["cost"]


@pytest.mark.unit
class TestBuildUserPrompt:
    def test_standard_mode_wraps_whatif(self):
        result = build_user_prompt(whatif_content="Resource changes: 1")
        assert "<whatif_output>" in result
        assert "Resource changes: 1" in result
        assert "Analyze the following Azure What-If output" in result

    def test_ci_mode_includes_diff(self):
        result = build_user_prompt(whatif_content="changes", diff_content="diff --git a/main.bicep")
        assert "<code_diff>" in result
        assert "diff --git" in result

    def test_ci_mode_includes_bicep(self):
        result = build_user_prompt(
            whatif_content="changes",
            diff_content="diff",
            bicep_content="param location string",
        )
        assert "<bicep_source>" in result
        assert "param location string" in result

    def test_ci_mode_no_bicep_when_none(self):
        result = build_user_prompt(
            whatif_content="changes", diff_content="diff", bicep_content=None
        )
        assert "<bicep_source>" not in result

    def test_pr_metadata_in_prompt(self):
        result = build_user_prompt(
            whatif_content="changes",
            diff_content="diff",
            pr_title="Add storage",
            pr_description="Adding new storage account",
        )
        assert "<pull_request_intent>" in result
        assert "Add storage" in result
        assert "Adding new storage account" in result

    def test_pr_title_only(self):
        result = build_user_prompt(
            whatif_content="changes",
            diff_content="diff",
            pr_title="Add storage",
        )
        assert "Add storage" in result
        assert "Not provided" in result  # description defaults

    def test_standard_mode_no_pr_metadata(self):
        result = build_user_prompt(whatif_content="changes")
        assert "<pull_request_intent>" not in result
