# coding=utf-8
from __future__ import unicode_literals, print_function, absolute_import


from .model_event import DataChangeEvent, TableLocalDataChangeEvent, TableForeignKeyChangeEvent, TableManyToManyFieldChangeEvent
from .data import DataSourceChangeEvent, DataRelationChangeEvent
from .django_data import DjangoDataSourceManager


class EventBridge(object):

    def __init__(self, django_data_source_manager, event_callback):
        assert isinstance(django_data_source_manager, DjangoDataSourceManager)
        assert callable(event_callback)

        self._ddsm = django_data_source_manager
        self._event_callback = event_callback

    def process_table_event(self, table_event):
        self.static_process_table_event(
            ddsm=self._ddsm,
            event_callback=self._event_callback,
            table_event=table_event,
        )

    @staticmethod
    def static_process_table_event(ddsm, event_callback, table_event):
        assert isinstance(table_event, DataChangeEvent)
        if isinstance(table_event, TableLocalDataChangeEvent):
            ds = ddsm.get_table_data_source(table_event.table)
            if not ds:
                return
            event_callback(
                DataSourceChangeEvent(
                    data_source=ds,
                    pk=table_event.pk,
                    is_create=table_event.is_create,
                    is_delete=table_event.is_delete,
                )
            )
        elif isinstance(table_event, TableForeignKeyChangeEvent):
            dr = ddsm.get_foreign_column_data_relation(table_event.table, table_event.column)
            if not dr:
                return
            event_callback(
                DataRelationChangeEvent(
                    data_relation=dr,
                    primary_pk=table_event.pk,
                    is_create=table_event.old_value is None,
                    is_delete=table_event.new_value is None,
                )
            )
            if table_event.old_value is not None:
                event_callback(
                    DataRelationChangeEvent(
                        data_relation=dr.reversed,
                        primary_pk=table_event.old_value,
                        is_create=False,
                        is_delete=True,
                    )
                )
            if table_event.new_value is not None:
                event_callback(
                    DataRelationChangeEvent(
                        data_relation=dr.reversed,
                        primary_pk=table_event.new_value,
                        is_create=True,
                        is_delete=False,
                    )
                )
        elif isinstance(table_event, TableManyToManyFieldChangeEvent):
            dr = ddsm.get_many_to_many_table_data_relation(table_event.through_table)
            if not dr:
                return
            event_callback(
                DataRelationChangeEvent(
                    data_relation=dr,
                    primary_pk=table_event.primary_pk,
                    is_create=table_event.is_create,
                    is_delete=table_event.is_delete,
                )
            )
            event_callback(
                DataRelationChangeEvent(
                    data_relation=dr.reversed,
                    primary_pk=table_event.secondary_pk,
                    is_create=table_event.is_create,
                    is_delete=table_event.is_delete,
                )
            )
        else:
            raise ValueError("Unknown Table Event: {}".format(type(table_event)))

