from plone.registry.interfaces import IInterfaceAwareRecord
from plone.registry.interfaces import IRecordAddedEvent
from plone.registry.interfaces import IRecordEvent
from plone.registry.interfaces import IRecordModifiedEvent
from plone.registry.interfaces import IRecordRemovedEvent
from plone.registry.recordsproxy import RecordsProxy
from zope.component import adapter
from zope.component import subscribers
from zope.interface import implementer


@implementer(IRecordEvent)
class RecordEvent:
    def __init__(self, record):
        self.record = record

    def __repr__(self):
        return f"<{self.__class__.__name__} for {self.record.__name__}>"


@implementer(IRecordAddedEvent)
class RecordAddedEvent(RecordEvent):
    """record added"""


@implementer(IRecordRemovedEvent)
class RecordRemovedEvent(RecordEvent):
    """record removed"""


@implementer(IRecordModifiedEvent)
class RecordModifiedEvent(RecordEvent):
    def __init__(self, record, oldValue, newValue):
        super().__init__(record)
        self.oldValue = oldValue
        self.newValue = newValue


@adapter(IRecordEvent)
def redispatchInterfaceAwareRecordEvents(event):
    """When an interface-aware record received a record event,
    redispatch the event in a similar manner to the IObjectEvent redispatcher.

    Note that this means one IRecordModifiedEvent will be fired for each
    change to a record.
    """

    record = event.record

    if not IInterfaceAwareRecord.providedBy(record):
        return

    schema = record.interface
    if schema is None:
        return

    proxy = RecordsProxy(record.__parent__, schema)

    adapters = subscribers((proxy, event), None)
    for ad in adapters:
        pass  # getting them does the work
