import unittest

from analogai.foundation.common.utils.expression_factory import ExpressionFactory


class TestNotionCaptionParser(unittest.TestCase):
    def setUp(self):
        self.factory = ExpressionFactory()



    def test_contextual_appositive(self):
        expression = self.factory.create_notion_expression("John, the programmer")
        if expression.caption.lower() == "john":
            self.assertEqual(len(expression.context), 1)
            self.assertEqual(expression.context[0].caption.lower(), "programmer")
        else:
            self.assertEqual(expression.caption.lower(), "john, the programmer")
            self.assertEqual(len(expression.context), 0)


    def test_article_head_is_stripped(self):
        expression = self.factory.create_notion_expression("the imperor")
        self.assertIn(expression.caption.lower(), {"imperor", "the imperor"})
        self.assertEqual(len(expression.context), 0)

    def test_alexander_the_great_without_comma_is_single_notion(self):
        expression = self.factory.create_notion_expression("alexander the great")
        self.assertEqual(expression.caption.lower(), "alexander the great")
        self.assertEqual(len(expression.context), 0)

    def test_alexander_comma_the_great_has_nested_context(self):
        expression = self.factory.create_notion_expression("alexander, the great")
        if expression.caption.lower() == "alexander":
            self.assertEqual(len(expression.context), 1)
            self.assertEqual(expression.context[0].caption.lower(), "great")
        else:
            self.assertEqual(expression.caption.lower(), "alexander, the great")
            self.assertEqual(len(expression.context), 0)

    def test_giorgi_comma_the_doctor_has_nested_context(self):
        expression = self.factory.create_notion_expression("Giorgi, the doctor")
        if expression.caption.lower() == "giorgi":
            self.assertEqual(len(expression.context), 1)
            self.assertEqual(expression.context[0].caption.lower(), "doctor")
        else:
            self.assertEqual(expression.caption.lower(), "giorgi, the doctor")
            self.assertEqual(len(expression.context), 0)

    def test_parses_or_as_single_caption(self):
        expression = self.factory.create_notion_expression("smoking or alcohol")
        self.assertEqual(expression.caption.lower(), "smoking or alcohol")
        self.assertEqual(len(expression.children), 0)

    def test_parses_and_as_single_caption(self):
        expression = self.factory.create_notion_expression("smoking and drinking")
        self.assertEqual(expression.caption.lower(), "smoking and drinking")
        self.assertEqual(len(expression.children), 0)

    def test_parses_or_with_three_items_as_single_caption(self):
        expression = self.factory.create_notion_expression("smoking or alcohol or drugs")
        self.assertEqual(expression.caption.lower(), "smoking or alcohol or drugs")
        self.assertEqual(len(expression.children), 0)

    def test_parses_and_with_contextual_as_single_caption(self):
        expression = self.factory.create_notion_expression("alexander, the great and socrates, the philosopher")
        self.assertEqual(expression.caption.lower(), "alexander, the great and socrates, the philosopher")
        self.assertEqual(len(expression.children), 0)

    def test_preserves_placeholder(self):
        expression = self.factory.create_notion_expression("respondent")
        self.assertEqual(expression.caption, "respondent")


if __name__ == "__main__":
    unittest.main()
