from typing import (
    List,
    Optional,
)
from xml.etree import cElementTree as eTree

from application.interactor import BurnBenefitInteractor, UnlockBenefitInteractor
from application.model import BenefitControllerDto, OperationDescription
from application.model.configuration import Configurations
from application.repository.pos import DBRepository


class BenefitRetryInteractor(object):

    def __init__(self, configs, db_repository, burn_benefit_interactor, unlock_benefit_interactor):
        # type: (Configurations, DBRepository, BurnBenefitInteractor, UnlockBenefitInteractor) -> None

        self.configs = configs
        self.logger = self.configs.logger
        self.db_repository = db_repository
        self.burn_interactor = burn_benefit_interactor
        self.unlock_interactor = unlock_benefit_interactor

    def get_pending_operations_benefits(self):
        # type: () -> Optional[List[BenefitControllerDto]]

        return self.db_repository.find_pending_operations()

    def perform_operations_on_pending_benefits(self, pending_operations):
        # type: (List[BenefitControllerDto]) -> None

        for benefit in pending_operations:
            if not benefit.order_picture:
                self.db_repository.change_benefit_operation_status_to_error(
                    benefit.benefit_id
                )
                continue

            order_picture = eTree.XML(benefit.order_picture)
            pos_id = order_picture.get("posId")

            if benefit.operation_description == OperationDescription.BURNED:
                self.burn_interactor.burn_benefit(
                    benefit_id=benefit.benefit_id,
                    originator_pos_id=pos_id,
                    benefit_applier=benefit.benefit_applier,
                    order_picture=eTree.XML(benefit.order_picture),
                    table_picture=eTree.XML(benefit.table_picture) if benefit.table_picture else None,
                    retry_quantity=benefit.retry_quantity,
                )

            elif benefit.operation_description == OperationDescription.UNLOCKED:
                self.unlock_interactor.unlock_benefit(
                    benefit_id=benefit.benefit_id,
                    originator_pos_id=pos_id,
                    benefit_applier=benefit.benefit_applier,
                    order_picture=eTree.XML(benefit.order_picture),
                    table_picture=eTree.XML(benefit.table_picture) if benefit.table_picture else None,
                    retry_quantity=benefit.retry_quantity,
                )
