from unittest.mock import Mock


def test_custom_role_restriction_phrasing(cnl_renderer, mock_has_pet, mock_dog):
    """Test custom phrasing for role restrictions as described in README."""
    from rdflib import URIRef

    # Configure a custom phrase for the has_pet property
    # Format: (singular, plural, prompt)
    custom_phrase = ("has a pet {}", "have pets {}", "What pets does {} have?")
    prop_uri = URIRef(mock_has_pet.iri)
    cnl_renderer.relevant_role_restriction_cnl_phrasing[prop_uri] = custom_phrase

    # Enable custom rendering
    cnl_renderer.custom_role_rendering = True

    # Test render_role_restriction
    rendered = cnl_renderer.render_role_restriction(
        mock_has_pet, operand1="The person", operand2="a dog"
    )

    # Expect: "The person has a pet a dog" (based on the format string in code)
    # The code does: property_phrase = f"{operand1} {custom_phrases[0].format(operand2)}"
    assert "has a pet a dog" in rendered


def test_reflexive_role_rendering(cnl_renderer):
    """Test rendering of reflexive roles as described in README."""
    from rdflib import URIRef
    from owlready2 import Restriction, base, ThingClass, owl

    # Mock a reflexive property
    mock_interacts = Mock()
    mock_interacts.iri = "http://purl.obolibrary.org/obo/RO_0002481"
    mock_interacts.label = ["interacts with"]

    # Configure reflexive customization
    prop_uri = URIRef(mock_interacts.iri)
    cnl_renderer.reflexive_property_customization[prop_uri] = (
        "that interacts with itself"
    )

    # Create a mock restriction: interacts some Self
    # Note: In owlready2, Self restriction is usually represented specially.
    # The code checks: isinstance(owl_class.value, ThingClass) and owl_class.type == HAS_SELF

    # We need to mock the restriction structure that extract_definitional_phrases expects
    mock_restriction = Mock(spec=Restriction)
    mock_restriction.property = mock_interacts
    mock_restriction.type = base.HAS_SELF
    mock_restriction.value = Mock(
        spec=ThingClass
    )  # Value is usually the class itself or Thing

    # We need to test this via extract_definitional_phrases as render_owl_class raises NotImplemented for HAS_SELF
    # but extract_definitional_phrases handles it specially.

    definitional_phrases = []

    # We need to ensure the group key logic works for this mock
    cnl_renderer.concept_group_key = Mock(
        return_value=cnl_renderer.RESTRICTION_START_KEY
    )
    cnl_renderer.is_restriction_key = Mock(return_value=True)
    cnl_renderer.is_logical_construct_key = Mock(return_value=False)

    # Mock search result for the property since extract_definitional_phrases looks it up
    cnl_renderer.ontology.search = Mock(return_value=[mock_interacts])

    cnl_renderer.extract_definitional_phrases(
        definitional_phrases=definitional_phrases,
        owl_classes=[mock_restriction],
        owl_class_definition="TestClass",
        owl_class_id="TestClass",
        owl_class_name_phrase="the test class",
    )

    # Expected: "It that interacts with itself" or similar
    assert any(
        "that interacts with itself" in phrase for phrase in definitional_phrases
    )
