#!/usr/bin/env python
#
# Copyright 2017 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import structlog
from netconf.nc_rpc.rpc import Rpc
import netconf.nc_common.error as ncerror
from twisted.internet.defer import inlineCallbacks, returnValue
import dicttoxml

log = structlog.get_logger()


class Get(Rpc):
    def __init__(self, request, request_xml, grpc_client, session,
                 capabilities):
        super(Get, self).__init__(request, request_xml, grpc_client, session,
                                  capabilities)
        self.service = None
        self.method = None
        self.metadata = None
        self._validate_parameters()

    @inlineCallbacks
    def execute(self):
        if self.rpc_response.is_error:
            returnValue(self.rpc_response)

        log.info('get-request', session=self.session.session_id,
                 request=self.request)

        rpc = self.get_voltha_rpc(self.request)
        if not rpc:
            log.info('unsupported-request', request=self.request)
            self.rpc_response.is_error = True
            self.rpc_response.node = ncerror.NotImpl(self.request_xml)
            returnValue(self.rpc_response)

        # Extract the service and method name from the rpc
        command = rpc.split('-')
        if len(command) != 2:
            log.debug('unsupported-rpc', rpc=rpc)
            self.rpc_response.is_error = True
            self.rpc_response.node = ncerror.NotImpl(self.request_xml)
            returnValue(self.rpc_response)

        self.service = command[0]
        self.method = command[1]
        self.params = {}
        if self.request.has_key('metadata'):
            self.metadata = self.request['metadata']

        # Execute the request
        res_dict, yang_options = yield self.grpc_client.invoke_voltha_rpc(
            service=self.service,
            method=self.method,
            params=self.params,
            metadata=self.metadata)

        # convert dict to xml
        xml = dicttoxml.dicttoxml(res_dict, attr_type=True)
        log.info('voltha-info', res=res_dict, xml=xml)

        root_elem = self.get_root_element(xml)

        # Build the yang response
        self.rpc_response.node = self.rpc_response.build_yang_response(
            root_elem, self.request, yang_options=yang_options)
        self.rpc_response.is_error = False

        returnValue(self.rpc_response)

    def _validate_parameters(self):
        log.info('validate-parameters', session=self.session.session_id)
        # Validate the GET command
        if self.request:
            try:
                if self.request['command'] != 'get':
                    self.rpc_response.is_error = True
                    self.rpc_response.node = ncerror.BadMsg(self.request_xml)
                    return

                if self.request.has_key('filter'):
                    if not self.request.has_key('class'):
                        self.rpc_response.is_error = True
                        self.rpc_response.node = ncerror.NotImpl(
                            self.request_xml)
                    return

            except Exception as e:
                self.rpc_response.is_error = True
                self.rpc_response.node = ncerror.ServerException(
                    self.request_xml)
                return

    def get_voltha_rpc(self, request):
        if request.has_key('class'):
            rpcs = self.rpc_request_mapping.get(request['class'])
            if rpcs is None:
                return None
            for rpc in rpcs:
                if request.has_key('subclass'):
                    # search first for subclass
                    if rpc['subclass'] and request['subclass'] == rpc[
                        'subclass']:
                        return rpc['rpc']

            # If the request has a subclass and is not in the list of
            # supported rpc then return None
            if request.has_key('subclass'):
                return None

            # If we are here then no subclass exists.  Just return the rpc
            # associated with theNone subclass
            for rpc in rpcs:
                if rpc['subclass'] is None:
                    return rpc['rpc']

        return None

    # Supported Get Methods
    rpc_request_mapping = {
        'Voltha': [
            {'subclass': None,
             'rpc': 'VolthaGlobalService-GetVoltha'
             }],
        'VolthaInstance': [
            {'subclass': None,
             'rpc': 'VolthaLocalService-GetVolthaInstance'
             },
            {'subclass': 'health',
             'rpc': 'VolthaLocalService-GetHealth'
             },
            {'subclass': 'adapters',
             'rpc': 'VolthaLocalService-ListAdapters'
             },
            {'subclass': 'logical_devices',
             'rpc': 'VolthaLocalService-ListLogicalDevices'
             },
            {'subclass': 'devices',
             'rpc': 'VolthaLocalService-ListDevices'
             },
            {'subclass': 'device_types',
             'rpc': 'VolthaLocalService-ListDeviceTypes'
             },
            {'subclass': 'device_groups',
             'rpc': 'VolthaLocalService-ListDeviceGroups'
             },
        ],
        'VolthaInstances': [
            {'subclass': None,
             'rpc': 'VolthaGlobalService-ListVolthaInstances'
             }],
    }
