import logging

from bustoken import (
    TK_MAINTENANCE_TERMINATE_REQUEST,
    TK_MAINTENANCE_RESTART_REQUEST,
    TK_MAINTENANCE_RECREATE_FILES_XML,
    TK_MAINTENANCE_RECREATE_FILE_NUMBER,
    TK_MAINTENANCE_CLEAN_AUDIT_LOG,
)
from events import (
    CleanDatabasesProcessor,
    MaintenanceProcessor
)
from messagehandler import EventHandler
from msgbus import MBEasyContext, TK_SYS_ACK, TK_SYS_NAK
from systools import sys_log_exception


logger = logging.getLogger("Maintenance")


class MaintenanceEventHandler(EventHandler):
    def __init__(
        self,
        mb_context,                 # type: MBEasyContext
        maintenance_processor,      # type: MaintenanceProcessor
        clean_databases_processor   # type: CleanDatabasesProcessor
    ):
        # type: (...) -> None

        super(MaintenanceEventHandler, self).__init__(mb_context)
        self.mb_context = mb_context
        self.maintenance_processor = maintenance_processor
        self.clean_databases_processor = clean_databases_processor

    def subscribe_events(self, subject):
        return

    def terminate_event(self):
        return

    @staticmethod
    def get_handled_tokens():
        return [
            TK_MAINTENANCE_TERMINATE_REQUEST,
            TK_MAINTENANCE_RESTART_REQUEST,
            TK_MAINTENANCE_RECREATE_FILES_XML,
            TK_MAINTENANCE_RECREATE_FILE_NUMBER
        ]

    def handle_event(self, subject, _, __, ___):
        logger.info("Event received: [{}]".format(subject))

        if not self.maintenance_processor.is_inside_maintenance_window():
            logger.info("Not inside maintenance window. Exiting...")
            return

        if subject == "CleanDatabaseBackups":
            self.clean_databases_processor.clean_database_backups()
        elif subject == "CleanDatabases":
            self.clean_databases_processor.clean_databases()
            self.clean_databases_processor.vacuum_databases()

    def handle_message(self, msg):
        try:
            if msg.token == TK_MAINTENANCE_TERMINATE_REQUEST:
                response = self.maintenance_processor.handle_terminate_request(msg)
            elif msg.token == TK_MAINTENANCE_RESTART_REQUEST:
                response = self.maintenance_processor.handle_restart_request(msg)
            elif msg.token == TK_MAINTENANCE_CLEAN_AUDIT_LOG:
                response = self.maintenance_processor.clean_audit_log()
            else:
                response = (False, "")

            msg.token = TK_SYS_ACK if response[0] else TK_SYS_NAK
            self.mb_context.MB_ReplyMessage(msg, data=response[1])
        except Exception as ex:
            sys_log_exception("Unexpected exception handling event: {}".format(msg.token))
            msg.token = TK_SYS_NAK
            self.mb_context.MB_ReplyMessage(msg, data=str(ex))
