from tornado import gen

from intranet.search.abovemeta.decider.rules import definitions_by_language_scope
from intranet.search.abovemeta.decider.decider_context import SelectContext


@gen.coroutine
def cast(rule, context, requester):
    with context(rule) as wizard_context:
        trigger = rule.trigger

        with wizard_context(trigger) as trigger_context:
            triggered = yield trigger(trigger_context, requester=requester)
            if not triggered:
                raise gen.Return(False)

            trigger_context['triggered'] = True

        wizard_context['triggered'] = True

    context['rating'] = sum(context['weights'])

    raise gen.Return(True)


@gen.coroutine
def select(state, requester):
    language = state.language
    scope = state.scope

    context = SelectContext.initial(state)

    casts = []
    spells_attrs = []
    result = []

    for zone, zone_rules in definitions_by_language_scope[
            (language, scope)].items():

        if zone == 'wizard' and state.page > 0:
            # вызываем колдунщики только на первой странице
            continue

        if (zone in state.forced_wizards and
                state.forced_wizards[zone] in [r.name for r in zone_rules]):
            for rule in zone_rules:
                if rule.name == state.forced_wizards[zone]:
                    final_context = context.copy()
                    final_context['rating'] = 10
                    result.append([True, (rule, final_context)])
                    continue
        else:
            for rule in zone_rules:
                final_context = context.copy()
                casts.append(cast(rule, final_context, requester))
                spells_attrs.append((rule, final_context))

    triggers = yield casts

    result += list(zip(triggers, spells_attrs))

    raise gen.Return(result)
