#
# -*- coding: utf-8 -*-
#
# This file is part of reclass
#

import copy
import pyparsing as pp

from item import Item
from reclass.utils.dictpath import DictPath
from reclass.errors import ExpressionError, UndefinedVariableError

_VAR = 'VAR'
_TEST = 'TEST'
_VALUE = 'VALUE'

_IF = 'IF'
_EQUAL = '=='
_NOT_EQUAL = '!='

class ExpItem(Item):

    def _get_parser():

        def _variable(string, location, tokens):
            token = tokens[0]
            tokens[0] = (_VAR, token)

        def _test(string, location, tokens):
            token = tokens[0]
            tokens[0] = (_TEST, token)

        def _if(string, location, tokens):
            token = tokens[0]
            tokens[0] = (_IF, token)

        _EXCLUDES = '?!='
        _END_IF = '?'

        white_space = pp.White().suppress()
        end = pp.StringEnd()
        operator = (pp.Literal(_EQUAL) | pp.Literal(_NOT_EQUAL)).setParseAction(_test)
        end_if = pp.Literal(_END_IF).setParseAction(_if)
        not_operator = ~pp.Literal(_EQUAL) + ~pp.Literal(_NOT_EQUAL) + ~pp.Literal(_END_IF)
        variable = not_operator + pp.Word(pp.printables).setParseAction(_variable)
        item = (operator | end_if | variable) + (white_space | end)
        expr = pp.Optional(white_space) + pp.OneOrMore(item)
        return expr

    _parser = _get_parser()

    def __init__(self, item, delimiter):
        self._delimiter = delimiter
        self._type = None
        self._refs = []
        self._expr = []
        self._parse_expression(item.render(None, None))

    def _parse_expression(self, expr):
        try:
            self._expr = ExpItem._parser.parseString(expr).asList()
        except pp.ParseException as e:
            raise ParseError(e.msg, e.line, e.col, e.lineno)

        if len(self._expr) == 1 and self._expr[0][0] == _VAR:
            self._type = _VALUE
            return
        elif len(self._expr) == 5 and self._expr[0][0] == _VAR and self._expr[1][0] == _TEST and self._expr[2][0] == _VAR and self._expr[3][0] == _IF and self._expr[4][0] == _VAR:
            self._type = _TEST
            export, parameter, value = self._get_vars(self._expr[0][1], None, None, None)
            export, parameter, value = self._get_vars(self._expr[2][1], export, parameter, value)
            if parameter != None:
                path = DictPath(self._delimiter, parameter).drop_first()
                self._ref.append(str(path))
            return
        raise ExpressionError('Failed to parse %s' % str(self))

    def contents(self):
        return self._expr

    def has_exports(self):
        return True

    def has_references(self):
        return len(self._refs) > 0

    def get_references(self):
        return self._refs

    def _resolve(self, path, dictionary):
        try:
            return path.get_value(dictionary)
        except KeyError as e:
            raise UndefinedVariableError(str(path))

    def _value_expression(self, exports):
        result = []
        path = DictPath(self._delimiter, self._expr[0][1]).drop_first()
        for node, items in exports.iteritems():
            if path.exists_in(items):
                value = { node: copy.deepcopy(self._resolve(path, items)) }
                result.append(value)
        return result

    def _if_expression(self, context, exports):
        export_path = None
        parameter_path = None
        parameter_value = None
        test = None
        value_path = DictPath(self._delimiter, self._expr[4][1])

        if self._expr[1][1] == _EQUAL:
            test = _EQUAL
        elif self._expr[1][1] == _NOT_EQUAL:
            test = _NOT_EQUAL

        export_path, parameter_path, parameter_value = self._get_vars(self._expr[0][1], export_path, parameter_path, parameter_value)
        export_path, parameter_path, parameter_value = self._get_vars(self._expr[2][1], export_path, parameter_path, parameter_value)

        if parameter_path != None:
            parameter_path.drop_first()
            parameter_value = str(self._resolve(parameter, context))

        if export_path is None or parameter_value is None or test is None or value_path is None:
            ExpressionError('Failed to render %s' % str(self))

        export_path.drop_first()
        value_path.drop_first()

        results = []
        for node, items in exports.iteritems():
            if export_path.exists_in(items):
                export_value = str(self._resolve(export_path, items))
                test_passed = False
                if test == _EQUAL and export_value == parameter_value:
                    test_passed = True
                elif test == _NOT_EQUAL and export_value != parameter_value:
                    test_passed = True
                if test_passed:
                    result = { node: copy.deepcopy(self._resolve(value_path, items)) }
                    results.append(result)
        return results

    def _get_vars(self, var, export, parameter, value):
        if isinstance(var, str):
            path = DictPath(self._delimiter, var)
            if path.path[0] == 'exports':
                export = path
            elif path.path[0] == 'SELF':
                parameter = path
            else:
                value = var
        else:
            value = var
        return export, parameter, value

    def render(self, context, exports):
        if self._type == _VALUE:
            return self._value_expression(exports)
        elif self._type == _TEST:
            return self._if_expression(context, exports)
        raise ExpressionError('Failed to render %s' % str(self))

    def __str__(self):
        return ' '.join(str(j) for i,j in self._expr)

    def __repr__(self):
        return 'ExpItem(%r)' % self._expr
