from decimal import Decimal
import logging

from quixote.publish import get_publisher

from wcs.qommon import _
from wcs.qommon.substitution import Substitutions
from wcs.publisher import WcsPublisher

from .abelium_domino_ui import (is_activated, abelium_domino_ws, get_client, get_family)

SESSION_CACHE = 'abelium_domino_variable_cache'

class DominoVariables(object):
    VARIABLE_TEMPLATE = 'domino_var_%s'
    CHILD_VARIABLE_TEMPLATE = 'domino_var_%s_enfant%s'

    CHILD_COLUMNS = abelium_domino_ws.Child.COLUMNS
    FAMILY_COLUMNS = abelium_domino_ws.Family.COLUMNS \
        + abelium_domino_ws.Family.MORE_COLUMNS
    def __init__(self, publisher=None, request=None):
        self.publisher = publisher
        self.request = request

    def get_substitution_variables(self):
        vars = {}
        if not is_activated() or not self.request or not self.request.user \
                or not getattr(self.request.user, 'email'):
            return vars

        # test cache
        cache = getattr(self.request.session, SESSION_CACHE, None)
        if cache is not None:
            return cache
        # call the web service
        try:
            charset = get_publisher().site_charset
            family = get_family(self.request.user)
            if family:
                family.complete()
                for i, child in enumerate(family.children):
                    for remote_name, name, converter, desc in self.CHILD_COLUMNS:
                        v = getattr(child, name, None)
                        if v is None:
                            continue
                        if hasattr(v, 'encode'):
                            v = v.encode(charset)
                        vars[self.CHILD_VARIABLE_TEMPLATE % (name, i+1)] = v
                vars[self.VARIABLE_TEMPLATE % 'nombre_enfants'] = len(family.children)
                for remote_name, name, converted, desc in self.FAMILY_COLUMNS:
                    if hasattr(family, name):
                        v = getattr(family, name)
                        if v is None:
                            continue
                        if hasattr(v, 'encode'):
                            v = v.encode(charset)
                        vars[self.VARIABLE_TEMPLATE % name] = v
                amount = Decimal(0)
                for invoice in family.invoices:
                    amount += invoice.reste_du
                if amount:
                    vars['user_famille_reste_du'] = str(amount)
        except abelium_domino_ws.DominoException:
            logging.exception('unable to call the domino ws for user %s', self.request.user.id)
        setattr(self.request.session, SESSION_CACHE, vars)
        self.request.session.store()
        return vars

    def get_substitution_variables_list(cls):
        if not is_activated():
            return ()
        vars = []
        for remote_name, name, converted, desc in cls.FAMILY_COLUMNS:
            vars.append((_('Domino'), cls.VARIABLE_TEMPLATE % name, desc))
        for remote_name, name, converted, desc in cls.CHILD_COLUMNS:
            vars.append((_('Domino'), cls.CHILD_VARIABLE_TEMPLATE % (name, '{0,1,2,..}'), desc))
        return vars
    get_substitution_variables_list = classmethod(get_substitution_variables_list)

Substitutions.register_dynamic_source(DominoVariables)
WcsPublisher.register_extra_source(DominoVariables)
