import resqpy.olio.uuid as bu
from resqpy.olio.base import BaseResqpy


class DummyObj(BaseResqpy):
   resqml_type = 'DummyResqmlInterpretation'


class ReusableDummyObj(BaseResqpy):
   resqml_type = 'ReusableDummyResqmlInterpretation'

   # a class must have this method to allow meaningful reusability
   def is_equivalent(self, other):
      return True


def test_base_creation(tmp_model):

   # Setup new object
   title = 'Wondermuffin'
   dummy = DummyObj(model = tmp_model, title = title)

   # UUID should exist
   # but root should not exist yet and part name does not exist in the parent model
   assert dummy.uuid is not None
   #   assert dummy.part is not None  # this version constructed the part from resqml_type and uuid
   assert dummy.part is None
   assert dummy.root is None

   # After creating XML, root should exist
   dummy.create_xml(add_as_part = True)
   assert dummy.root is not None


def test_base_save_and_load(tmp_model):

   # Create and save a DummyObj
   title = 'feefifofum'
   originator = 'Scruffian'
   metadata = {"balderdash": "pumpernickel"}
   dummy1 = DummyObj(model = tmp_model, title = title, originator = originator)
   dummy1.extra_metadata = metadata

   # Save to XML
   dummy1.create_xml(add_as_part = True)

   # Load a new object
   dummy2 = DummyObj(model = tmp_model, uuid = dummy1.uuid)

   # Properties should match
   assert bu.matching_uuids(dummy2.uuid, dummy1.uuid)
   assert dummy2.root is not None
   assert dummy2.title == title
   assert dummy2.originator == originator
   assert dummy2.extra_metadata == metadata


def test_base_comparison(tmp_model):

   # Setup new object
   dummy1 = DummyObj(model = tmp_model)
   dummy2 = DummyObj(model = tmp_model, uuid = dummy1.uuid)  # Same UUID
   dummy3 = DummyObj(model = tmp_model, title = 'hello')  # Different UUID

   # Comparison should work by UUID
   assert dummy1 == dummy2
   assert dummy1 != dummy3


def test_base_repr(tmp_model):

   dummy = DummyObj(model = tmp_model)

   # Check repr method produces a string
   rep = repr(dummy)
   assert isinstance(rep, str)
   assert len(rep) > 0

   # Check HTML can be generated
   html = dummy._repr_html_()
   assert len(html) > 0


def test_base_reuse_duplicate(tmp_model):

   # Create object and save
   dummy_1 = ReusableDummyObj(model = tmp_model)
   assert not dummy_1.try_reuse()
   dummy_1.create_xml(add_as_part = True)

   # Should be present in model
   uuids = tmp_model.uuids(obj_type = ReusableDummyObj.resqml_type)
   assert len(uuids) == 1
   assert dummy_1.try_reuse()  # after a part has had xml created and added to model, it is reusable

   # Create duplicate object
   dummy_2 = ReusableDummyObj(model = tmp_model)
   assert not bu.matching_uuids(dummy_1.uuid, dummy_2.uuid)
   assert dummy_2.try_reuse()  # should have matched dummy_1
   assert bu.matching_uuids(dummy_1.uuid, dummy_2.uuid)

   # Only one 'RESQML' object should exist in model, despite us having two resqpy objects
   uuids = tmp_model.uuids(obj_type = ReusableDummyObj.resqml_type)
   assert len(uuids) == 1
   assert bu.matching_uuids(uuids[0], dummy_2.uuid)
