import gi

from chrysacase import ChrysalideTestCase
from gi.repository import GObject
from pychrysalide.glibext import ComparableObject, HashableObject, SingletonCandidate, SingletonFactory


class TestSingleton(ChrysalideTestCase):
    """Test cases for pychrysalide.glibext.SingletonFactory."""


    def testSingletonCandidateCreation(self):
        """Create objects with SingletonCandidate interface."""

        with self.assertRaisesRegex(NotImplementedError, 'SingletonCandidate can not be constructed'):

            sc = SingletonCandidate()


        class NewSingletonImplem(gi._gi.GObject, HashableObject, ComparableObject, SingletonCandidate):
            pass

        nsi = NewSingletonImplem()

        self.assertIsNotNone(nsi)


        class NewSingletonImplem2(GObject.Object, HashableObject, ComparableObject, SingletonCandidate):
            pass

        nsi2 = NewSingletonImplem2()

        self.assertIsNotNone(nsi2)


    # def testFactoryCreation(self):
    #     """Create singleton factories."""

    #     sf = SingletonFactory()

    #     self.assertIsNotNone(sf)

    #     class MyFactory(SingletonFactory):
    #         pass

    #     msf = MyFactory()

    #     self.assertIsNotNone(msf)





    # def testSingletonMethods(self):
    #     """Test the singleton methods."""

    #     class IntegerCacheImplem(GObject.Object, SingletonCandidate):

    #         def __init__(self, val):
    #             super().__init__()
    #             self._val = val

    #         def _list_inner_instances(self):
    #             return ()

    #         def __hash__(self):
    #             return hash('common-key')

    #         def __eq__(self, other):
    #             return self._val == other._val

    #     val_0 = IntegerCacheImplem(0)
    #     val_0_bis = IntegerCacheImplem(0)
    #     val_1 = IntegerCacheImplem(1)

    #     self.assertEqual(hash(val_0), hash(val_0_bis))
    #     self.assertEqual(hash(val_0), hash(val_1))

    #     self.assertEqual(val_0.hash(), val_0_bis.hash())
    #     self.assertEqual(val_0.hash(), val_1.hash())

    #     self.assertTrue(val_0 == val_0_bis)
    #     self.assertFalse(val_0 == val_1)


    # def testSingletonFootprint(self):
    #     """Check for singleton memory footprint."""

    #     sf = SingletonFactory()


    #     class IntegerCacheImplem(GObject.Object, SingletonCandidate):

    #         def __init__(self, val):
    #             super().__init__()
    #             self._val = val

    #         def _list_inner_instances(self):
    #             return ()

    #         def __hash__(self):
    #             return hash('common-key')

    #         def __eq__(self, other):
    #             return self._val == other._val

    #         def _set_read_only(self):
    #             pass

    #     val_0 = IntegerCacheImplem(0)
    #     val_0_bis = IntegerCacheImplem(0)
    #     val_1 = IntegerCacheImplem(1)

    #     obj = sf.get_instance(val_0)

    #     self.assertTrue(obj is val_0)

    #     obj = sf.get_instance(val_0_bis)

    #     self.assertTrue(obj is val_0)

    #     obj = sf.get_instance(val_1)

    #     self.assertTrue(obj is val_1)

    #     self.assertEqual(len(obj.inner_instances), 0)


    #     class MasterCacheImplem(GObject.Object, SingletonCandidate):

    #         def __init__(self, children):
    #             super().__init__()
    #             self._children = children

    #         def _list_inner_instances(self):
    #             return self._children

    #         def _update_inner_instances(self, instances):
    #             self._children = instances

    #         def __hash__(self):
    #             return hash('master-key')

    #         def __eq__(self, other):
    #             return False

    #         def _set_read_only(self):
    #             pass

    #     master = MasterCacheImplem(( val_0_bis, val_1 ))

    #     obj = sf.get_instance(master)

    #     self.assertTrue(obj.inner_instances[0] is val_0)

    #     self.assertTrue(obj.inner_instances[1] is val_1)