import unittest
from analogai.deepthink.presentation.parsers.parsers_factory import build_message_parser


class TestParserCombinations(unittest.TestCase):
    def setUp(self):
        self.sentence_parser = build_message_parser()

    def test_sentence_combinations(self):
        combinations = [
            (
                '{"intent":"making_statement","subject":"smoke","relationship":"causes","object":"cancer","probability":1.0}',
                {"relation_name": "causes"},
            ),
            (
                '{"intent":"making_statement","subject":"socrates","relationship":"is_a","object":"human","probability":1.0}',
                {"relation_name": "is"},
            ),
            (
                '{"intent":"making_statement","location":"Tbilisi","subject":"it","relationship":"do","object":"rain","probability":1.0}',
                {"relation_name": "do", "location": "Tbilisi"},
            ),
            (
                '{"intent":"making_statement","time":"today","probability":0.5,"subject":"it","relationship":"do","object":"rain"}',
                {"from_time": "today", "probability": 0.5, "relation_name": "do"},
            ),
            (
                '{"intent":"making_statement","location":"Tbilisi","time":"tomorrow","deontic":"permitted","subject":"agent","relationship":"sell","object":"macbook pro","probability":1.0}',
                {"location": "Tbilisi", "from_time": "tomorrow", "deontic_modality": "permitted", "relation_name": "sell"},
            ),
            (
                '{"intent":"making_statement","deontic":"obligatory","subject":"you","relationship":"read","object":"books","probability":1.0}',
                {"deontic_modality": "obligatory", "relation_name": "read"},
            ),
            (
                '{"intent":"making_statement","time":"tomorrow","time_from":"14:00","time_to":"16:00","subject":"it","relationship":"do","object":"rain","probability":1.0}',
                {"from_time": "tomorrow 14:00", "to_time": "tomorrow 16:00", "relation_name": "do"},
            ),
        ]
        for text, expectations in combinations:
            with self.subTest(text=text[:60]):
                parsed_list = self.sentence_parser.parse(text)
                self.assertTrue(parsed_list, f"Expected parse for: {text[:60]}")
                parsed = parsed_list[0]
                for key, expected in expectations.items():
                    if key == "relation_name":
                        self.assertEqual(parsed.data.relation.value if parsed.data.relation else None, expected, f"key={key}")
                    else:
                        self.assertEqual(getattr(parsed.data, key), expected, f"key={key}")

    def test_sentence_returns_none_for_plain_text(self):
        for text in ["human be mortal", "smoking cause cancer", "smoke causes cancer"]:
            with self.subTest(text=text):
                self.assertEqual([], self.sentence_parser.parse(text))

    def test_sentence_without_modal_has_none_context(self):
        parsed_list = self.sentence_parser.parse('{"intent":"making_statement","subject":"socrates","relationship":"is_a","object":"human","probability":1.0}')
        self.assertTrue(parsed_list)
        parsed = parsed_list[0]
        self.assertIsNone(parsed.data.location)
        self.assertIsNone(parsed.data.deontic_modality)
        self.assertIsNone(parsed.data.from_time)
        self.assertIsNone(parsed.data.to_time)


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