import unittest
from analogai.foundation.core.value_objects.modifier import Modifier
from analogai.foundation.common.utils.modifier_utils import ModifierBuilder
from analogai.foundation.core.value_objects.time import Time
from analogai.foundation.common.enums.deontic_modality import DeonticModality

class TestModifierBuilder(unittest.TestCase):
    
    def test_build_empty_context(self):
        builder = ModifierBuilder()
        context = builder.build()
        
        self.assertIsNone(context.location)
        self.assertIsNone(context.deontic_modality)
        self.assertIsNone(context.from_time)
        self.assertIsNone(context.to_time)
    
    def test_with_location(self):
        context = ModifierBuilder().with_location("Paris").build()
        
        self.assertEqual(context.location, "Paris")
        self.assertIsNone(context.deontic_modality)
        self.assertIsNone(context.from_time)
        self.assertIsNone(context.to_time)
    
    def test_with_deontic_modality(self):
        context = ModifierBuilder().with_deontic_modality(DeonticModality.FORBIDDEN).build()
        
        self.assertIsNone(context.location)
        self.assertEqual(context.deontic_modality, DeonticModality.FORBIDDEN)
        self.assertIsNone(context.from_time)
        self.assertIsNone(context.to_time)
    
    def test_with_from_time_full(self):
        context = ModifierBuilder().with_from_time(
            year=2024, month=1, day=1, hour=10, minute=30
        ).build()
        
        self.assertIsNotNone(context.from_time)
        self.assertEqual(context.from_time.year, 2024)
        self.assertEqual(context.from_time.month, 1)
        self.assertEqual(context.from_time.day, 1)
        self.assertEqual(context.from_time.hour, 10)
        self.assertEqual(context.from_time.minute, 30)
    
    def test_with_from_time_partial(self):
        context = ModifierBuilder().with_from_time(year=2024, month=1).build()
        
        self.assertIsNotNone(context.from_time)
        self.assertEqual(context.from_time.year, 2024)
        self.assertEqual(context.from_time.month, 1)
        self.assertIsNone(context.from_time.day)
        self.assertIsNone(context.from_time.hour)
        self.assertIsNone(context.from_time.minute)
    
    def test_with_to_time_full(self):
        context = ModifierBuilder().with_to_time(
            year=2024, month=12, day=31, hour=23, minute=59
        ).build()
        
        self.assertIsNotNone(context.to_time)
        self.assertEqual(context.to_time.year, 2024)
        self.assertEqual(context.to_time.month, 12)
        self.assertEqual(context.to_time.day, 31)
        self.assertEqual(context.to_time.hour, 23)
        self.assertEqual(context.to_time.minute, 59)
    
    def test_fluent_interface(self):
        context = (ModifierBuilder()
                   .with_location("Tokyo")
                   .with_deontic_modality(DeonticModality.PERMITTED)
                   .with_from_time(year=2024, month=1)
                   .with_to_time(year=2024, month=12)
                   .build())
        
        self.assertEqual(context.location, "Tokyo")
        self.assertEqual(context.deontic_modality, DeonticModality.PERMITTED)
        self.assertIsNotNone(context.from_time)
        self.assertEqual(context.from_time.year, 2024)
        self.assertEqual(context.from_time.month, 1)
        self.assertIsNotNone(context.to_time)
        self.assertEqual(context.to_time.year, 2024)
        self.assertEqual(context.to_time.month, 12)
    
    def test_multiple_calls_override(self):
        builder = ModifierBuilder()
        context1 = builder.with_location("Paris").build()
        context2 = builder.with_location("London").build()
        
        self.assertEqual(context1.location, "Paris")
        self.assertEqual(context2.location, "London")

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