# -*- coding: utf-8 -*-

import os
from messagehandler import MessageHandler
from helper import (
    config_logger,
    import_pydevd
)
from threading import Thread

import cfgtools
import pyscripts
from msgbus import MBEasyContext
from systools import sys_parsefilepath
from eventhandler import MaintenanceEventHandler
from events import MaintenanceProcessor, CleanDatabasesProcessor
from dbapitransactioncallback import DbApiTransactionCallback
from dbrepository import SqliteOrderRepository, SqliteFiscalRepository
from services import CommonService


def main():
    import_pydevd(os.environ["LOADERCFG"], 9128)

    required_services = "StoreWideConfig|Persistence|PosController"

    config_logger(os.environ["LOADERCFG"], 'Maintenance')
    config = cfgtools.read(os.environ["LOADERCFG"])

    mb_context = MBEasyContext("MaintenanceComp")
    pyscripts.mbcontext = mb_context

    start_hour = int(config.find_value("MaintenanceComponent.StartHour", default=5))
    end_hour = int(config.find_value("MaintenanceComponent.EndHour", default=6))

    comp_no = int(config.find_value("MaintenanceComponent.Number"))

    files_to_delete = config.find_values("MaintenanceComponent.DeleteFiles") or []
    dirs_to_delete = config.find_values("MaintenanceComponent.DeleteDirs") or []
    server_dirs_to_delete = config.find_values("MaintenanceComponent.DeleteServerDirs") or []

    common_service = CommonService(mb_context)
    maintenance_processor = MaintenanceProcessor(mb_context, common_service, comp_no, start_hour, end_hour)
    clean_databases_processor = None

    component_is_server = comp_no == 0
    if component_is_server:
        fiscal_path = sys_parsefilepath(config.find_value("MaintenanceComponent.XmlFiscalPath", default=""))
        parse_file_path = config.find_value("MaintenanceComponent.XmlFiscalEnviados", default="Enviados")
        fiscal_sent_path = sys_parsefilepath(parse_file_path)
        audit_path = sys_parsefilepath(config.find_value("MaintenanceComponent.AuditLogPath"))
        days_to_purge_audit_log = config.find_value("MaintenanceComponent.DaysToKeepAuditLogFiles", default=90)
        database_backups_to_keep = config.find_value("MaintenanceComponent.DatabaseBackupFilesToKeep", default=3)
        database_backups_to_keep = int(database_backups_to_keep)

        maintenance_processor.set_server_parameters(fiscal_path, audit_path, fiscal_sent_path, days_to_purge_audit_log)

        order_ddl_path = config.find_value("MaintenanceComponent.OrderSchemaDatabasePath", default='')
        fiscal_ddl_path = config.find_value("MaintenanceComponent.FiscalSchemaDatabasePath", default='')
        data_path = sys_parsefilepath("{HVDATADIR}")
        database_dir = os.path.join(data_path, "databases")
        backup_database_dir = os.path.join(data_path, "backups_maintenance/databases")
        order_schema_sql_path = os.path.join(data_path, order_ddl_path)
        fiscal_schema_sql_path = os.path.join(data_path, fiscal_ddl_path)

        db_api_callback = DbApiTransactionCallback()
        sqlite_order_repository = SqliteOrderRepository(
            common_service,
            database_dir,
            backup_database_dir,
            order_schema_sql_path,
            db_api_callback
        )

        sqlite_fiscal_repository = SqliteFiscalRepository(
            database_dir,
            backup_database_dir,
            fiscal_schema_sql_path,
            db_api_callback
        )

        clean_databases_processor = CleanDatabasesProcessor(
            mb_context,
            comp_no,
            database_backups_to_keep,
            sqlite_order_repository,
            sqlite_fiscal_repository,
            common_service
        )

    maintenance_event_handler = MaintenanceEventHandler(mb_context,
                                                        maintenance_processor,
                                                        clean_databases_processor)

    message_handler = MessageHandler(
        mb_context,
        "Maintenance%02d" % comp_no,
        "MaintenanceComp",
        required_services,
        maintenance_event_handler
    )

    if component_is_server:
        clean_databases_processor.set_server_parameters(maintenance_processor)
        delete_old_databases_thread = Thread(target=clean_databases_processor.clean_database_backups)
        delete_old_databases_thread.start()

    if files_to_delete:
        maintenance_processor.delete_files(files_to_delete)

    if dirs_to_delete or server_dirs_to_delete:
        maintenance_processor.delete_dirs(dirs_to_delete, server_dirs_to_delete)

    message_handler.subscribe_events(["CleanDatabaseBackups", "CleanDatabases", "VacuumDatabases"])
    message_handler.handle_events()
