import logging
from datetime import datetime, timedelta
from threading import Lock

from sysactions import action
from application.interactor import NDiscountInteractor, NCouponInteractor

coupons_available_cache = None
last_cache_time = None
lock = Lock()
logger = logging.getLogger("PosActions")


@action
def is_coupon_component_available(pos_id, seconds_to_renew_cache=3600):
    is_coupon_component_connected(pos_id, seconds_to_renew_cache=seconds_to_renew_cache)

    global coupons_available_cache
    return str(coupons_available_cache).lower()


def is_coupon_component_connected(pos_id, seconds_to_renew_cache=3600):
    global last_cache_time
    global coupons_available_cache

    with lock:
        now = datetime.now()
        seconds_to_renew = _get_seconds_to_renew(seconds_to_renew_cache)
        if coupons_available_cache is None or _reached_seconds_to_renew_cache(now, seconds_to_renew):
            coupons_available_cache = _test_connection_coupon_discount_components(pos_id)
            last_cache_time = now
        return coupons_available_cache


def _get_seconds_to_renew(seconds_to_renew_cache):
    seconds_to_renew = 180
    try:
        seconds_to_renew = int(seconds_to_renew_cache)
    except TypeError as _:
        pass
    return seconds_to_renew


def _reached_seconds_to_renew_cache(now, seconds_to_renew_cache):
    return not last_cache_time or now > last_cache_time + timedelta(seconds=seconds_to_renew_cache)


def _test_connection_coupon_discount_components(pos_id):
    coupon_interactor = NCouponInteractor()
    discount_interactor = NDiscountInteractor()
    test_coupon = coupon_interactor.test_connection(pos_id)
    test_discount = discount_interactor.test_connection()
    return test_coupon and test_discount
