from xml.etree import cElementTree as eTree

from application.model import (
    BenefitAppliers,
    OperationDescription,
)
from application.model.configuration import Configurations
from application.model.repository.benefit_applier import DefaultBenefitApplierRepository
from application.repository.pos import DBRepository
from typing import (
    Optional,
    Dict,
)

from application.services import TableService


class BurnBenefitInteractor(object):
    def __init__(
        self,                               # type: BurnBenefitInteractor
        configs,                            # type: Configurations
        db_repository,                      # type: DBRepository
        benefit_appliers_repositories,      # type: Dict[BenefitAppliers: DefaultBenefitApplierRepository]
        table_service,                      # type: TableService
    ):
        # type: (...) -> None

        self.configs = configs
        self.logger = self.configs.logger
        self.db_repository = db_repository
        self.benefit_appliers_repositories = benefit_appliers_repositories
        self.table_service = table_service

    def burn_benefit(
        self,                   # type: BurnBenefitInteractor
        benefit_id,             # type: str
        originator_pos_id,      # type: int
        benefit_applier,        # type: str
        order_picture,          # type: eTree
        table_picture=None,     # type: Optional[eTree]
        retry_quantity=0        # type: Optional[int]
    ):
        # type: (...) -> None

        success = False
        applier_name = benefit_applier.split("|")[0]
        try:
            message = "Burning benefit. BenefitId: {}; OriginatorPosId: {}; BenefitApplier: {}; Try: {}"
            self.logger.info(message.format(benefit_id, originator_pos_id, applier_name, retry_quantity))
            if benefit_applier not in [None, 'None', '']:
                if not table_picture:
                    table_picture = self.table_service.get_table_picture(
                        pos_id=originator_pos_id,
                        order_picture=order_picture,
                    )

                self.benefit_appliers_repositories[applier_name].burn_benefit(
                    benefit_id=benefit_id,
                    order_picture=order_picture,
                    table_picture=table_picture,
                )
            success = True
        except Exception as _:
            self.logger.exception("Error burning benefit: {}".format(benefit_id))
        finally:
            self.db_repository.manage_operation_status(
                success,
                benefit_id,
                OperationDescription.BURNED,
                applier_name,
                retry_quantity,
                order_picture=order_picture,
                table_picture=table_picture,
            )
