#// Copyright (c) 2000-2018 Ericsson Telecom AB                                                         //
#// All rights reserved. This program and the accompanying materials are made available under the terms //
#// of the Eclipse Public License v2.0 which accompanies this distribution, and is available at         //
#// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html                                                           //
#/////////////////////////////////////////////////////////////////////////////////////////////////////////
import json, logging
from fnmatch import fnmatch
from Common.DsRestAPI import DsRestAPI
from Help import DSHELP

class DataSource:
    '''The DataSource handler'''

    SOURCE_ID = 'DataSource'

    def __init__(self, directory):
        self._logger = logging.getLogger(__name__)
        self._handlers = {}
        self._dsRestAPI = DsRestAPI(self._getDataHandler, self._setDataHandler)

    def setHandlers(self, handlers):
        self._handlers = handlers

    def _getDataHandler(self, request, userCredentials):
        if request['source'] == self.SOURCE_ID:
            return self._handleBuildInGetData(request, userCredentials)
        elif request['source'] in self._handlers:
            return self._handlers[request['source']]['getDataHandler'](request, userCredentials)

    def _setDataHandler(self, request, userCredentials):
        if request['source'] == self.SOURCE_ID:
            return None
        elif request['source'] in self._handlers:
            return self._handlers[request['source']]['setDataHandler'](request, userCredentials)

    def _handleBuildInGetData(self, request, userCredentials):
        element = request['element']
        params = request['params']

        if element == 'help':
            help = {'sources': [{'source': self.SOURCE_ID, 'dataElements': DSHELP}]}
            for handlerName in self._handlers:
                if handlerName != self.SOURCE_ID:
                    try:
                        helpResponse = self._handlers[handlerName]['getDataHandler']({'source': handlerName, 'element': 'help', 'params': []}, userCredentials)
                        if helpResponse is not None:
                            handlerHelp = json.loads(helpResponse['node']['val'].decode('hex'))
                            for sourceHelp in handlerHelp['sources']:
                                help['sources'].append(sourceHelp)
                    except:
                        self._logger.exception('Failed to get help for ' + handlerName)
            return {'node': {'val': json.dumps(help).encode('hex'), 'tp': 5}}
        elif element == 'Sources':
            return {'list': [{'node': {'val': handlerName, 'tp': 10}} for handlerName in self._handlers]}
        elif element == 'not' and len(params) == 1:
            return {'node': {'val': self._bool2string(params[0]['paramValue'] != 'true'), 'tp': 3}}
        elif element == '==' and len(params) == 2:
            return {'node': {'val': self._bool2string(params[0]['paramValue'] == params[1]['paramValue']), 'tp': 3}}
        elif element == '!=' and len(params) == 2:
            return {'node': {'val': self._bool2string(params[0]['paramValue'] != params[1]['paramValue']), 'tp': 3}}
        elif element == '>' and len(params) == 2:
            return {'node': {'val': self._bool2string(float(params[0]['paramValue']) > float(params[1]['paramValue'])), 'tp': 3}}
        elif element == '>=' and len(params) == 2:
            return {'node': {'val': self._bool2string(float(params[0]['paramValue']) >= float(params[1]['paramValue'])), 'tp': 3}}
        elif element == '<' and len(params) == 2:
            return {'node': {'val': self._bool2string(float(params[0]['paramValue']) < float(params[1]['paramValue'])), 'tp': 3}}
        elif element == '<=' and len(params) == 2:
            return {'node': {'val': self._bool2string(float(params[0]['paramValue']) <= float(params[1]['paramValue'])), 'tp': 3}}
        elif element == 'and':
            return {'node': {'val': self._bool2string(reduce(lambda x, y: x and y, [self._string2bool(param['paramValue']) for param in params], True)), 'tp': 3}}
        elif element == 'or':
            return {'node': {'val': self._bool2string(reduce(lambda x, y: x or y, [self._string2bool(param['paramValue']) for param in params], False)), 'tp': 3}}
        elif element == 'match' and len(params) == 2:
            return {'node': {'val': self._bool2string(fnmatch(params[0]['paramValue'], params[1]['paramValue'])), 'tp': 3}}
        elif element == 'not match' and len(params) == 2:
            return {'node': {'val': self._bool2string(not fnmatch(params[0]['paramValue'], params[1]['paramValue'])), 'tp': 3}}
        elif element == 'sum' and len(params) == 1:
            return {'node': {'val': str(sum([float(string) for string in json.loads(params[0]['paramValue'])])), 'tp': 2}}
        elif element == 'exists' and len(params) == 1:
            return {'node': {'val': self._bool2string(reduce(lambda x, y: x or y, [self._string2bool(string) for string in json.loads(params[0]['paramValue'])], False)), 'tp': 3}}
        elif element == 'forAll' and len(params) == 1:
            return {'node': {'val': self._bool2string(reduce(lambda x, y: x and y, [self._string2bool(string) for string in json.loads(params[0]['paramValue'])], True)), 'tp': 3}}
        elif element == 'dataElementPresent':
            origSource, origElement, origParams = self._getRequestPartsFromParams(params)
            response = self._getDataHandler({'source': origSource, 'element': origElement, 'params': origParams}, userCredentials)
            if response is not None:
                return {'node': {'val': 'true', 'tp': 3}}
            else:
                return {'node': {'val': 'false', 'tp': 3}}
        elif element == 'sizeOf':
            origSource, origElement, origParams = self._getRequestPartsFromParams(params)
            response = self._getDataHandler({'source': origSource, 'element': origElement, 'params': origParams}, userCredentials)
            size = 1
            if 'list' in response:
                size = len(response['list'])
            return {'node': {'val': str(size), 'tp': 1}}

    def _getRequestPartsFromParams(self, params):
        origSource = ''
        origElement = ''
        origParams = []
        i = 0
        while i < len(params):
            param = params[i]
            if param['paramName'] == 'Source':
                origSource = param['paramValue']
            elif param['paramName'] == 'Element':
                origElement = param['paramValue']
            elif param['paramName'] == 'ParamName':
                i += 1
                if i < len(params) and params[i]['paramName'] == 'ParamValue':
                    origParams.append({'paramName': param['paramValue'], 'paramValue': params[i]['paramValue']})
                else:
                    return {'node': {'val': 'A ParamValue must always follow a ParamName parameter.', 'tp': 4}}
            i += 1
        return origSource, origElement, origParams


    def _bool2string(self, bool):
        if bool:
            return 'true'
        else:
            return 'false'

    def _string2bool(self, string):
        return string == 'true'

    def handleMessage(self, method, path, headers, body, userCredentials, response):
        response['body'] = json.dumps(self._dsRestAPI.parseRequest(json.loads(body), userCredentials))
        response['headers']['Content-Type'] = 'application/json'

    def getDataSourceHandlers(self):
        return {
            self.SOURCE_ID: {
                'getDataHandler': self._getDataHandler,
                'setDataHandler': self._setDataHandler
            }
        }

    def close(self):
        pass