#!/usr/bin/env python
# -*- coding: utf-8 -*-

##
# Copyright 2015 Telefonica Investigacion y Desarrollo, S.A.U.
# This file is part of openvim
# All Rights Reserved.
#
# 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.
#
# For those usages not covered by the Apache License, Version 2.0 please
# contact with: nfvlabs@tid.es
##

"""
Implement the plugging for OpendayLight openflow controller
It creates the class OF_conn to create dataplane connections
with static rules based on packet destination MAC address
"""

__author__="Pablo Montes, Alfonso Tierno"
__date__ ="$28-oct-2014 12:07:15$"


import json
import requests
import base64
import logging
import openflow_conn


class OF_conn(openflow_conn.OpenflowConn):
    """OpenDayLight connector. No MAC learning is used"""

    def __init__(self, params):
        """ Constructor.
            Params: dictionary with the following keys:
                of_dpid:     DPID to use for this controller
                of_ip:       controller IP address
                of_port:     controller TCP port
                of_user:     user credentials, can be missing or None
                of_password: password credentials
                of_debug:    debug level for logging. Default to ERROR
                other keys are ignored
            Raise an exception if same parameter is missing or wrong
        """

        # check params
        if "of_ip" not in params or params["of_ip"]==None or "of_port" not in params or params["of_port"]==None:
            raise ValueError("IP address and port must be provided")

        openflow_conn.OpenflowConn.__init__(self, params)
        # internal variables
        self.name = "OpenDayLight"
        self.headers = {'content-type': 'application/json', 'Accept': 'application/json'}
        self.auth=None
        self.pp2ofi={}  # From Physical Port to OpenFlow Index
        self.ofi2pp={}  # From OpenFlow Index to Physical Port

        self.dpid = str(params["of_dpid"])
        self.id = 'openflow:'+str(int(self.dpid.replace(':', ''), 16))
        self.url = "http://%s:%s" %( str(params["of_ip"]), str(params["of_port"] ) )
        if "of_user" in params and params["of_user"]!=None:
            if not params.get("of_password"):
                of_password=""
            else:
                of_password=str(params["of_password"])
            self.auth = base64.b64encode(str(params["of_user"])+":"+of_password)
            self.headers['Authorization'] = 'Basic '+self.auth

        self.logger = logging.getLogger('vim.OF.ODL')
        self.logger.setLevel( getattr(logging, params.get("of_debug", "ERROR")) )

    def get_of_switches(self):
        """
        Obtain a a list of switches or DPID detected by this controller
        :return: list length, and a list where each element a tuple pair (DPID, IP address)
                 Raise an OpenflowconnConnectionException exception if fails with text_error
        """
        try:
            of_response = requests.get(self.url+"/restconf/operational/opendaylight-inventory:nodes",
                                       headers=self.headers)
            error_text = "Openflow response %d: %s" % (of_response.status_code, of_response.text)
            if of_response.status_code != 200:
                self.logger.warning("get_of_switches " + error_text)
                raise openflow_conn.OpenflowconnUnexpectedResponse("Error get_of_switches " + error_text)

            self.logger.debug("get_of_switches " + error_text)
            info = of_response.json()

            if type(info) != dict:
                self.logger.error("get_of_switches. Unexpected response, not a dict: %s", str(info))
                raise openflow_conn.OpenflowconnUnexpectedResponse("Unexpected response, not a dict. Wrong version?")

            nodes = info.get('nodes')
            if type(nodes) is not dict:
                self.logger.error("get_of_switches. Unexpected response at 'nodes', not found or not a dict: %s", str(type(info)))
                raise openflow_conn.OpenflowconnUnexpectedResponse("Unexpected response at 'nodes', not found or "
                                                                   "not a dict. Wrong version?")

            node_list = nodes.get('node')
            if type(node_list) is not list:
                self.logger.error("get_of_switches. Unexpected response, at 'nodes':'node', "
                                  "not found or not a list: %s", str(type(node_list)))
                raise openflow_conn.OpenflowconnUnexpectedResponse("Unexpected response, at 'nodes':'node', not found "
                                                                   "or not a list. Wrong version?")

            switch_list=[]
            for node in node_list:
                node_id = node.get('id')
                if node_id is None:
                    self.logger.error("get_of_switches. Unexpected response at 'nodes':'node'[]:'id', not found: %s", str(node))
                    raise openflow_conn.OpenflowconnUnexpectedResponse("Unexpected response at 'nodes':'node'[]:'id', "
                                                                       "not found . Wrong version?")

                if node_id == 'controller-config':
                    continue

                node_ip_address = node.get('flow-node-inventory:ip-address')
                if node_ip_address is None:
                    self.logger.error("get_of_switches. Unexpected response at 'nodes':'node'[]:'flow-node-inventory:"
                                      "ip-address', not found: %s", str(node))
                    raise openflow_conn.OpenflowconnUnexpectedResponse("Unexpected response at 'nodes':'node'[]:"
                                                                       "'flow-node-inventory:ip-address', "
                                                                       "not found. Wrong version?")

                node_id_hex=hex(int(node_id.split(':')[1])).split('x')[1].zfill(16)
                switch_list.append( (':'.join(a+b for a,b in zip(node_id_hex[::2], node_id_hex[1::2])), node_ip_address))

            return len(switch_list), switch_list
        except requests.exceptions.RequestException as e:
            error_text = type(e).__name__ + ": " + str(e)
            self.logger.error("get_of_switches " + error_text)
            raise openflow_conn.OpenflowconnConnectionException(error_text)
        except ValueError as e:
            # ValueError in the case that JSON can not be decoded
            error_text = type(e).__name__ + ": " + str(e)
            self.logger.error("get_of_switches " + error_text)
            raise openflow_conn.OpenflowconnUnexpectedResponse(error_text)

    def obtain_port_correspondence(self):
        """
        Obtain the correspondence between physical and openflow port names
        :return: dictionary: with physical name as key, openflow name as value,
                 Raise a OpenflowconnConnectionException expection in case of failure
        """
        try:
            of_response = requests.get(self.url+"/restconf/operational/opendaylight-inventory:nodes",
                                       headers=self.headers)
            error_text = "Openflow response %d: %s" % (of_response.status_code, of_response.text)
            if of_response.status_code != 200:
                self.logger.warning("obtain_port_correspondence " + error_text)
                raise openflow_conn.OpenflowconnUnexpectedResponse(error_text)
            self.logger.debug("obtain_port_correspondence " + error_text)
            info = of_response.json()

            if type(info) != dict:
                self.logger.error("obtain_port_correspondence. Unexpected response not a dict: %s", str(info))
                raise openflow_conn.OpenflowconnUnexpectedResponse("Unexpected openflow response, not a dict. "
                                                                   "Wrong version?")

            nodes = info.get('nodes')
            if type(nodes) is not dict:
                self.logger.error("obtain_port_correspondence. Unexpected response at 'nodes', "
                                  "not found or not a dict: %s", str(type(nodes)))
                raise openflow_conn.OpenflowconnUnexpectedResponse("Unexpected response at 'nodes',not found or not a dict. Wrong version?")

            node_list = nodes.get('node')
            if type(node_list) is not list:
                self.logger.error("obtain_port_correspondence. Unexpected response, at 'nodes':'node', "
                                  "not found or not a list: %s", str(type(node_list)))
                raise openflow_conn.OpenflowconnUnexpectedResponse("Unexpected response, at 'nodes':'node', "
                                                                   "not found or not a list. Wrong version?")

            for node in node_list:
                node_id = node.get('id')
                if node_id is None:
                    self.logger.error("obtain_port_correspondence. Unexpected response at 'nodes':'node'[]:'id', "
                                      "not found: %s", str(node))
                    raise openflow_conn.OpenflowconnUnexpectedResponse("Unexpected response at 'nodes':'node'[]:'id', "
                                                                       "not found . Wrong version?")

                if node_id == 'controller-config':
                    continue

                # Figure out if this is the appropriate switch. The 'id' is 'openflow:' plus the decimal value
                # of the dpid
                #  In case this is not the desired switch, continue
                if self.id != node_id:
                    continue

                node_connector_list = node.get('node-connector')
                if type(node_connector_list) is not list:
                    self.logger.error("obtain_port_correspondence. Unexpected response at "
                                      "'nodes':'node'[]:'node-connector', not found or not a list: %s", str(node))
                    raise openflow_conn.OpenflowconnUnexpectedResponse("Unexpected response at 'nodes':'node'[]:"
                                                                       "'node-connector', not found  or not a list. "
                                                                       "Wrong version?")

                for node_connector in node_connector_list:
                    self.pp2ofi[ str(node_connector['flow-node-inventory:name']) ] = str(node_connector['id'] )
                    self.ofi2pp[ node_connector['id'] ] =  str(node_connector['flow-node-inventory:name'])

                node_ip_address = node.get('flow-node-inventory:ip-address')
                if node_ip_address is None:
                    self.logger.error("obtain_port_correspondence. Unexpected response at 'nodes':'node'[]:"
                                      "'flow-node-inventory:ip-address', not found: %s", str(node))
                    raise openflow_conn.OpenflowconnUnexpectedResponse("Unexpected response at 'nodes':'node'[]:"
                                                                       "'flow-node-inventory:ip-address', not found. Wrong version?")
                self.ip_address = node_ip_address

                # If we found the appropriate dpid no need to continue in the for loop
                break

            # print self.name, ": obtain_port_correspondence ports:", self.pp2ofi
            return self.pp2ofi
        except requests.exceptions.RequestException as e:
            error_text = type(e).__name__ + ": " + str(e)
            self.logger.error("obtain_port_correspondence " + error_text)
            raise openflow_conn.OpenflowconnConnectionException(error_text)
        except ValueError as e:
            # ValueError in the case that JSON can not be decoded
            error_text = type(e).__name__ + ": " + str(e)
            self.logger.error("obtain_port_correspondence " + error_text)
            raise openflow_conn.OpenflowconnUnexpectedResponse(error_text)

    def get_of_rules(self, translate_of_ports=True):
        """
        Obtain the rules inserted at openflow controller
        :param translate_of_ports:
        :return: dict if ok: with the rule name as key and value is another dictionary with the following content:
                    priority: rule priority
                    name:         rule name (present also as the master dict key)
                    ingress_port: match input port of the rule
                    dst_mac:      match destination mac address of the rule, can be missing or None if not apply
                    vlan_id:      match vlan tag of the rule, can be missing or None if not apply
                    actions:      list of actions, composed by a pair tuples:
                        (vlan, None/int): for stripping/setting a vlan tag
                        (out, port):      send to this port
                    switch:       DPID, all
                    Raise a OpenflowconnConnectionException expection in case of failure

        """

        try:
            # get rules
            if len(self.ofi2pp) == 0:
                self.obtain_port_correspondence()

            of_response = requests.get(self.url+"/restconf/config/opendaylight-inventory:nodes/node/" + self.id +
                                          "/table/0", headers=self.headers)
            error_text = "Openflow response %d: %s" % (of_response.status_code, of_response.text)

            # The configured page does not exist if there are no rules installed. In that case we return an empty dict
            if of_response.status_code == 404:
                return {}

            elif of_response.status_code != 200:
                self.logger.warning("get_of_rules " + error_text)
                raise openflow_conn.OpenflowconnUnexpectedResponse(error_text)

            self.logger.debug("get_of_rules " + error_text)

            info = of_response.json()

            if type(info) != dict:
                self.logger.error("get_of_rules. Unexpected response not a dict: %s", str(info))
                raise openflow_conn.OpenflowconnUnexpectedResponse("Unexpected openflow response, not a dict. "
                                                                   "Wrong version?")

            table = info.get('flow-node-inventory:table')
            if type(table) is not list:
                self.logger.error("get_of_rules. Unexpected response at 'flow-node-inventory:table', "
                                  "not a list: %s", str(type(table)))
                raise openflow_conn.OpenflowconnUnexpectedResponse("Unexpected response at 'flow-node-inventory:table',"
                                                                   " not a list. Wrong version?")

            flow_list = table[0].get('flow')
            if flow_list is None:
                return {}

            if type(flow_list) is not list:
                self.logger.error("get_of_rules. Unexpected response at 'flow-node-inventory:table'[0]:'flow', not a list: %s", str(type(flow_list)))
                raise openflow_conn.OpenflowconnUnexpectedResponse("Unexpected response at 'flow-node-inventory:"
                                                                   "table'[0]:'flow', not a list. Wrong version?")

            # TODO translate ports according to translate_of_ports parameter

            rules = dict()
            for flow in flow_list:
                if not ('id' in flow and 'match' in flow and 'instructions' in flow and
                                'instruction' in flow['instructions'] and
                                'apply-actions' in flow['instructions']['instruction'][0] and
                                'action' in flow['instructions']['instruction'][0]['apply-actions']):
                    raise openflow_conn.OpenflowconnUnexpectedResponse("unexpected openflow response, one or more "
                                                                       "elements are missing. Wrong version?")

                flow['instructions']['instruction'][0]['apply-actions']['action']

                rule = dict()
                rule['switch'] = self.dpid
                rule['priority'] = flow.get('priority')
                # rule['name'] = flow['id']
                # rule['cookie'] = flow['cookie']
                if 'in-port' in flow['match']:
                    in_port = flow['match']['in-port']
                    if not in_port in self.ofi2pp:
                        raise openflow_conn.OpenflowconnUnexpectedResponse("Error: Ingress port " + in_port +
                                                                           " is not in switch port list")

                    if translate_of_ports:
                        in_port = self.ofi2pp[in_port]

                    rule['ingress_port'] = in_port

                    if 'vlan-match' in flow['match'] and 'vlan-id' in flow['match']['vlan-match'] and \
                                'vlan-id' in flow['match']['vlan-match']['vlan-id'] and \
                                'vlan-id-present' in flow['match']['vlan-match']['vlan-id'] and \
                                flow['match']['vlan-match']['vlan-id']['vlan-id-present'] == True:
                        rule['vlan_id'] = flow['match']['vlan-match']['vlan-id']['vlan-id']

                    if 'ethernet-match' in flow['match'] and 'ethernet-destination' in flow['match']['ethernet-match'] and \
                        'address' in flow['match']['ethernet-match']['ethernet-destination']:
                        rule['dst_mac'] = flow['match']['ethernet-match']['ethernet-destination']['address']

                instructions=flow['instructions']['instruction'][0]['apply-actions']['action']

                max_index=0
                for instruction in instructions:
                    if instruction['order'] > max_index:
                        max_index = instruction['order']

                actions=[None]*(max_index+1)
                for instruction in instructions:
                    if 'output-action' in instruction:
                        if not 'output-node-connector' in instruction['output-action']:
                            raise openflow_conn.OpenflowconnUnexpectedResponse("unexpected openflow response, one or "
                                                                               "more elementa are missing. "
                                                                               "Wrong version?")

                        out_port = instruction['output-action']['output-node-connector']
                        if not out_port in self.ofi2pp:
                            raise openflow_conn.OpenflowconnUnexpectedResponse("Error: Output port " + out_port +
                                                                               " is not in switch port list")

                        if translate_of_ports:
                            out_port = self.ofi2pp[out_port]

                        actions[instruction['order']] = ('out',out_port)

                    elif 'strip-vlan-action' in instruction:
                        actions[instruction['order']] = ('vlan', None)

                    elif 'set-field' in instruction:
                        if not ('vlan-match' in instruction['set-field'] and 'vlan-id' in  instruction['set-field']['vlan-match'] and 'vlan-id' in instruction['set-field']['vlan-match']['vlan-id']):
                            raise openflow_conn.OpenflowconnUnexpectedResponse("unexpected openflow response, one or "
                                                                               "more elements are missing. "
                                                                               "Wrong version?")

                        actions[instruction['order']] = ('vlan', instruction['set-field']['vlan-match']['vlan-id']['vlan-id'])

                actions = [x for x in actions if x != None]

                rule['actions'] = list(actions)
                rules[flow['id']] = dict(rule)

                #flow['id']
                #flow['priority']
                #flow['cookie']
                #flow['match']['in-port']
                #flow['match']['vlan-match']['vlan-id']['vlan-id']
                # match -> in-port
                #      -> vlan-match -> vlan-id -> vlan-id
                #flow['match']['vlan-match']['vlan-id']['vlan-id-present']
                #TODO we asume that is not using rules with vlan-id-present:false
                #instructions -> instruction -> apply-actions -> action
                #instructions=flow['instructions']['instruction'][0]['apply-actions']['action']
                #Es una lista. Posibles elementos:
                #max_index=0
                #for instruction in instructions:
                #  if instruction['order'] > max_index:
                #    max_index = instruction['order']
                #actions=[None]*(max_index+1)
                #for instruction in instructions:
                #   if 'output-action' in instruction:
                #     actions[instruction['order']] = ('out',instruction['output-action']['output-node-connector'])
                #   elif 'strip-vlan-action' in instruction:
                #     actions[instruction['order']] = ('vlan', None)
                #   elif 'set-field' in instruction:
                #     actions[instruction['order']] = ('vlan', instruction['set-field']['vlan-match']['vlan-id']['vlan-id'])
                #
                #actions = [x for x in actions if x != None]
                #                                                       -> output-action -> output-node-connector
                #                                                       -> pop-vlan-action
            return rules
        except requests.exceptions.RequestException as e:
            error_text = type(e).__name__ + ": " + str(e)
            self.logger.error("get_of_rules " + error_text)
            raise openflow_conn.OpenflowconnConnectionException(error_text)
        except ValueError as e:
            # ValueError in the case that JSON can not be decoded
            error_text = type(e).__name__ + ": " + str(e)
            self.logger.error("get_of_rules " + error_text)
            raise openflow_conn.OpenflowconnUnexpectedResponse(error_text)

    def del_flow(self, flow_name):
        """
        Delete an existing rule
        :param flow_name: flow_name, this is the rule name
        :return: Raise a OpenflowconnConnectionException expection in case of failure
        """

        try:
            of_response = requests.delete(self.url+"/restconf/config/opendaylight-inventory:nodes/node/" + self.id +
                                          "/table/0/flow/"+flow_name, headers=self.headers)
            error_text = "Openflow response %d: %s" % (of_response.status_code, of_response.text)
            if of_response.status_code != 200:
                self.logger.warning("del_flow " + error_text)
                raise openflow_conn.OpenflowconnUnexpectedResponse(error_text)
            self.logger.debug("del_flow OK " + error_text)
            return None
        except requests.exceptions.RequestException as e:
            # raise an exception in case of contection error
            error_text = type(e).__name__ + ": " + str(e)
            self.logger.error("del_flow " + error_text)
            raise openflow_conn.OpenflowconnConnectionException(error_text)

    def new_flow(self, data):
        """
        Insert a new static rule
        :param data: dictionary with the following content:
                priority:     rule priority
                name:         rule name
                ingress_port: match input port of the rule
                dst_mac:      match destination mac address of the rule, missing or None if not apply
                vlan_id:      match vlan tag of the rule, missing or None if not apply
                actions:      list of actions, composed by a pair tuples with these posibilities:
                    ('vlan', None/int): for stripping/setting a vlan tag
                    ('out', port):      send to this port
        :return: Raise a OpenflowconnConnectionException expection in case of failure
        """

        try:

            if len(self.pp2ofi) == 0:
                self.obtain_port_correspondence()

            # We have to build the data for the opendaylight call from the generic data
            sdata = dict()
            sdata['flow-node-inventory:flow'] = list()
            sdata['flow-node-inventory:flow'].append(dict())
            flow = sdata['flow-node-inventory:flow'][0]
            flow['id'] = data['name']
            flow['flow-name'] = data['name']
            flow['idle-timeout'] = 0
            flow['hard-timeout'] = 0
            flow['table_id'] = 0
            flow['priority'] = data.get('priority')
            flow['match'] = dict()
            if not data['ingress_port'] in self.pp2ofi:
                error_text = 'Error. Port '+data['ingress_port']+' is not present in the switch'
                self.logger.warning("new_flow " + error_text)
                raise openflow_conn.OpenflowconnUnexpectedResponse(error_text)
            flow['match']['in-port'] = self.pp2ofi[data['ingress_port']]
            if 'dst_mac' in data:
                flow['match']['ethernet-match'] = dict()
                flow['match']['ethernet-match']['ethernet-destination'] = dict()
                flow['match']['ethernet-match']['ethernet-destination']['address'] = data['dst_mac']
            if data.get('vlan_id'):
                flow['match']['vlan-match'] = dict()
                flow['match']['vlan-match']['vlan-id'] = dict()
                flow['match']['vlan-match']['vlan-id']['vlan-id-present'] = True
                flow['match']['vlan-match']['vlan-id']['vlan-id'] = int(data['vlan_id'])
            flow['instructions'] = dict()
            flow['instructions']['instruction'] = list()
            flow['instructions']['instruction'].append(dict())
            flow['instructions']['instruction'][0]['order'] = 1
            flow['instructions']['instruction'][0]['apply-actions'] = dict()
            flow['instructions']['instruction'][0]['apply-actions']['action'] = list()
            actions = flow['instructions']['instruction'][0]['apply-actions']['action']

            order = 0
            for action in data['actions']:
                new_action = { 'order': order }
                if  action[0] == "vlan":
                    if action[1] == None:
                        # strip vlan
                        new_action['strip-vlan-action'] = dict()
                    else:
                        new_action['set-field'] = dict()
                        new_action['set-field']['vlan-match'] = dict()
                        new_action['set-field']['vlan-match']['vlan-id'] = dict()
                        new_action['set-field']['vlan-match']['vlan-id']['vlan-id-present'] = True
                        new_action['set-field']['vlan-match']['vlan-id']['vlan-id'] = int(action[1])
                elif action[0] == 'out':
                    new_action['output-action'] = dict()
                    if not action[1] in self.pp2ofi:
                        error_msj = 'Port '+action[1]+' is not present in the switch'
                        raise openflow_conn.OpenflowconnUnexpectedResponse(error_msj)

                    new_action['output-action']['output-node-connector'] = self.pp2ofi[ action[1] ]
                else:
                    error_msj = "Unknown item '%s' in action list" % action[0]
                    self.logger.error("new_flow " + error_msj)
                    raise openflow_conn.OpenflowconnUnexpectedResponse(error_msj)

                actions.append(new_action)
                order += 1

            # print json.dumps(sdata)
            of_response = requests.put(self.url+"/restconf/config/opendaylight-inventory:nodes/node/" + self.id +
                          "/table/0/flow/" + data['name'],
                                headers=self.headers, data=json.dumps(sdata) )
            error_text = "Openflow response %d: %s" % (of_response.status_code, of_response.text)
            if of_response.status_code != 200:
                self.logger.warning("new_flow " + error_text)
                raise openflow_conn.OpenflowconnUnexpectedResponse(error_text)
            self.logger.debug("new_flow OK " + error_text)
            return None

        except requests.exceptions.RequestException as e:
            # raise an exception in case of contection error
            error_text = type(e).__name__ + ": " + str(e)
            self.logger.error("new_flow " + error_text)
            raise openflow_conn.OpenflowconnConnectionException(error_text)

    def clear_all_flows(self):
        """
        Delete all existing rules
        :return: Raise a OpenflowconnConnectionException expection in case of failure
        """
        try:
            of_response = requests.delete(self.url+"/restconf/config/opendaylight-inventory:nodes/node/" + self.id +
                                      "/table/0", headers=self.headers)
            error_text = "Openflow response %d: %s" % (of_response.status_code, of_response.text)
            if of_response.status_code != 200 and of_response.status_code != 404: #HTTP_Not_Found
                self.logger.warning("clear_all_flows " + error_text)
                raise openflow_conn.OpenflowconnUnexpectedResponse(error_text)
            self.logger.debug("clear_all_flows OK " + error_text)
        except requests.exceptions.RequestException as e:
            error_text = type(e).__name__ + ": " + str(e)
            self.logger.error("clear_all_flows " + error_text)
            raise openflow_conn.OpenflowconnConnectionException(error_text)
