import json
from logging import Logger

from model.error_type import ExternalServicesErrorsType
from interactor.route.menu.get_ruptured_products.dto import (
    GetRupturedProductsResponse,
    GetRupturedProductsRequest
)
from model.exception import ExternalServiceErrors
from validation_util import validate_api_key
from messagebus import MessageBusException

from model.config import Config
from datetime import timedelta, datetime

from model.repository import PosRepositoryModel


class GetRupturedProducts(object):

    def __init__(self, logger, config, pos_repository, cache_menu_ruptured_items):
        # type: (Logger, Config, PosRepositoryModel, dict) -> None

        self.logger = logger
        self.config = config
        self.cache_menu_ruptured_items = cache_menu_ruptured_items
        self.pos_repository = pos_repository

    def execute(self, request):
        # type: (GetRupturedProductsRequest) -> dict

        validate_api_key(request, self.config.api_key_mapping)
        has_cached_data = self.cache_menu_ruptured_items.get("last_request_date")
        if has_cached_data:
            should_renew_cache = (datetime.today() - self.cache_menu_ruptured_items.get("last_request_date")) > \
                                 timedelta(seconds=self.config.ruptured_items_cache_time)
            if should_renew_cache:
                self.create_cache_data()
        else:
            self.create_cache_data()

        return self.cache_menu_ruptured_items.get("data")

    def create_cache_data(self):
        try:
            rupture_items = self.pos_repository.get_rupture_products()
        except MessageBusException:
            raise ExternalServiceErrors(ExternalServicesErrorsType.ServiceUnavailable)
        self.cache_menu_ruptured_items["last_request_date"] = datetime.today()
        response = GetRupturedProductsResponse(json.loads(rupture_items))
        self.cache_menu_ruptured_items["data"] = response.ruptured_products
