from messageprocessor import (
    MessageProcessorCallback,
    MessageProcessor,
)
from typing import (
    Any,
    List,
)

from ._ConnectionWrapper import ConnectionWrapper


class PersistTransactionCallback(MessageProcessorCallback):
    def __init__(
        self,
        conn,                                       # type: ConnectionWrapper
        do_not_need_transaction_processors=None,    # type: List[MessageProcessor]
    ):
        # type: (...) -> None

        self.conn = conn
        self.do_not_need_transaction = {}
        for processor in do_not_need_transaction_processors:
            self.do_not_need_transaction[processor.get_processor_name()] = True

    def process_begun(
        self,           # type: PersistTransactionCallback
        event_name,     # type: str
        request_id,     # type: str
        data,           # type: str
    ):
        # type: (...) -> None

        pass

    def input_parsed(
        self,           # type: PersistTransactionCallback
        event_name,     # type: str
        request_id,     # type: str
        input_obj,      # type: Any
    ):
        # type: (...) -> None

        if event_name not in self.do_not_need_transaction:
            self.conn.begin_transaction()

    def business_called(
        self,           # type: PersistTransactionCallback
        event_name,     # type: str
        request_id,     # type: str
        input_obj,      # type: Any
        output_obj,     # type: Any
    ):
        # type: (...) -> None

        if event_name not in self.do_not_need_transaction:
            self.conn.commit()

    def process_finished(
        self,           # type: PersistTransactionCallback
        event_name,     # type: str
        request_id,     # type: str
        input_obj,      # type: Any
        output_obj,     # type: Any
    ):
        # type: (...) -> None

        pass

    def parse_exception(
        self,           # type: PersistTransactionCallback
        event_name,     # type: str
        request_id,     # type: str
        data,           # type: Any
        exception,      # type: BaseException
    ):
        # type: (...) -> None

        pass

    def unhandled_exception(
        self,           # type: PersistTransactionCallback
        event_name,     # type: str
        request_id,     # type: str
        input_obj,      # type: Any
        exception,      # type: BaseException
    ):
        # type: (...) -> None

        if event_name not in self.do_not_need_transaction:
            self.conn.rollback()
