# -*- coding: utf-8 -*-
import logging

from oscar.apps.partner.strategy import Structured
from oscar.core.loading import get_classes

from ocyan.core.fender import config
from ocyan.core.utils import RequestCache

(
    ProductSpecifiedTaxInclusive,
    ProductSpecifiedTaxExclusive,
    UseCheapestChildProductStockRecord,
    StockRequired,
) = get_classes(
    "partner.mixins",
    [
        "ProductSpecifiedTaxInclusive",
        "ProductSpecifiedTaxExclusive",
        "UseCheapestChildProductStockRecord",
        "StockRequired",
    ],
)
logger = logging.getLogger(__name__)


class Selector(object):
    """
    Responsible for returning the appropriate strategy class for a given
    user/session.

    This can be called in three ways:

    #) Passing a request and user.  This is for determining
       prices/availability for a normal user browsing the site.

    #) Passing just the user.  This is for offline processes that don't
       have a request instance but do know which user to determine prices for.

    #) Passing nothing.  This is for offline processes that don't
       correspond to a specific user.  Eg, determining a price to store in
       a search index.

    """

    # pylint: disable=unused-argument
    def strategy(self, request=None, user=None, **kwargs):
        """
        Return an instanticated strategy instance
        """
        use_price_incl_tax = config.get("oscar", "use_price_incl_tax", True)
        if use_price_incl_tax:
            return NLInclusive(request)

        return NLExclusive(request)


# pylint: disable=abstract-method
class OncePerRequest(Structured):
    @RequestCache.once_per_request
    def fetch_for_product(self, product, stockrecord=None):
        return super(OncePerRequest, self).fetch_for_product(product, stockrecord)

    @RequestCache.once_per_request
    def fetch_for_parent(self, product):
        return super(OncePerRequest, self).fetch_for_parent(product)


class NLInclusive(
    UseCheapestChildProductStockRecord,
    StockRequired,
    ProductSpecifiedTaxInclusive,
    OncePerRequest,
):
    pass


class NLExclusive(
    UseCheapestChildProductStockRecord,
    StockRequired,
    ProductSpecifiedTaxExclusive,
    OncePerRequest,
):
    pass
