#// Copyright (c) 2000-2017 Ericsson Telecom AB                                                         //
#// All rights reserved. This program and the accompanying materials are made available under the terms //
#// of the Eclipse Public License v1.0 which accompanies this distribution, and is available at         //
#// http://www.eclipse.org/legal/epl-v10.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