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

##
# Copyright 2016, I2T Research Group (UPV/EHU)
# 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: alaitz.mendiola@ehu.eus or alaitz.mendiola@gmail.com
##

'''
ImplementS the pluging for the Open Network Operating System (ONOS) openflow
controller. It creates the class OF_conn to create dataplane connections
with static rules based on packet destination MAC address
'''

__author__="Alaitz Mendiola"
__date__ ="$22-nov-2016$"


import json
import requests
import base64
import logging

class OF_conn():
    '''ONOS 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 ?? Does a controller have a dpid?
                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")
        #internal variables
        self.name = "onos"
        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 = 'of:'+str(self.dpid.replace(':', ''))
        self.url = "http://%s:%s/onos/v1/" %( str(params["of_ip"]), str(params["of_port"] ) )

        # TODO This may not be straightforward
        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.onos')
        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
                >=0, list:      list length, and a list where each element a tuple pair (DPID, IP address)
                <0, text_error: if fails
        '''
        try:
            self.headers['content-type'] = 'text/plain'
            of_response = requests.get(self.url + "devices", 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)
                return -1, 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))
                return -1, "Unexpected response, not a dict. Wrong version?"

            node_list = info.get('devices')

            if type(node_list) is not list:
                self.logger.error(
                    "get_of_switches. Unexpected response, at 'devices', not found or not a list: %s",
                    str(type(node_list)))
                return -1, "Unexpected response, at 'devices', 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 'device':'id', not found: %s",
                                      str(node))
                    return -1, "Unexpected response at 'device':'id', not found . Wrong version?"

                node_ip_address = node.get('annotations').get('managementAddress')
                if node_ip_address is None:
                    self.logger.error(
                        "get_of_switches. Unexpected response at 'device':'managementAddress', not found: %s",
                        str(node))
                    return -1, "Unexpected response at 'device':'managementAddress', 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, 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)
            return -1, error_text


        
    def obtain_port_correspondence(self):
        '''Obtain the correspondence between physical and openflow port names
        return:
             0, dictionary: with physical name as key, openflow name as value
            -1, error_text: if fails
        '''
        try:
            self.headers['content-type'] = 'text/plain'
            of_response = requests.get(self.url + "devices/" + self.id + "/ports", 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)
                return -1, error_text

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

            node_connector_list = info.get('ports')
            if type(node_connector_list) is not list:
                self.logger.error(
                    "obtain_port_correspondence. Unexpected response at 'ports', not found or not a list: %s",
                    str(node_connector_list))
                return -1, "Unexpected response at 'ports', not found  or not a list. Wrong version?"

            for node_connector in node_connector_list:
                if (node_connector['port'] != "local"):
                    self.pp2ofi[str(node_connector['annotations']['portName'])] = str(node_connector['port'])
                    self.ofi2pp[str(node_connector['port'])] = str(node_connector['annotations']['portName'])

            node_ip_address = info['annotations']['managementAddress']
            if node_ip_address is None:
                self.logger.error(
                    "obtain_port_correspondence. Unexpected response at 'managementAddress', not found: %s",
                    str(self.id))
                return -1, "Unexpected response at 'managementAddress', not found. Wrong version?"
            self.ip_address = node_ip_address

            # print self.name, ": obtain_port_correspondence ports:", self.pp2ofi
            return 0, self.pp2ofi

        except (requests.exceptions.RequestException, 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)
            return -1, error_text
        
    def get_of_rules(self, translate_of_ports=True):
        ''' Obtain the rules inserted at openflow controller
            Params:
                translate_of_ports: if True it translates ports from openflow index to physical switch name
            Return:
                0, 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 
                -1, text_error if fails
        '''


        if len(self.ofi2pp) == 0:
            r, c = self.obtain_port_correspondence()
            if r < 0:
                return r, c
        # get rules
        try:
            of_response = requests.get(self.url + "flows/" + self.id, 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 0, {}

            elif of_response.status_code != 200:
                self.logger.warning("get_of_rules " + error_text)
                return -1, 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))
                return -1, "Unexpected openflow response, not a dict. Wrong version?"

            flow_list = info.get('flows')

            if flow_list is None:
                return 0, {}

            if type(flow_list) is not list:
                self.logger.error(
                    "get_of_rules. Unexpected response at 'flows', not a list: %s",
                    str(type(flow_list)))
                return -1, "Unexpected response at 'flows', not a list. Wrong version?"

            rules = dict() # Response dictionary

            for flow in flow_list:
                if not ('id' in flow and 'selector' in flow and 'treatment' in flow and \
                                    'instructions' in flow['treatment'] and 'criteria' in \
                                    flow['selector']):
                    return -1, "unexpected openflow response, one or more elements are missing. Wrong version?"

                rule = dict()
                rule['switch'] = self.dpid
                rule['priority'] = flow.get('priority')
                rule['name'] = flow['id']

                for criteria in flow['selector']['criteria']:
                    if criteria['type'] == 'IN_PORT':
                        in_port = str(criteria['port'])
                        if in_port != "CONTROLLER":
                            if not in_port in self.ofi2pp:
                                return -1, "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

                    elif criteria['type'] == 'VLAN_VID':
                        rule['vlan_id'] = criteria['vlanId']

                    elif criteria['type'] == 'ETH_DST':
                        rule['dst_mac'] = str(criteria['mac']).lower()

                actions = []
                for instruction in flow['treatment']['instructions']:
                    if instruction['type'] == "OUTPUT":
                        out_port = str(instruction['port'])
                        if out_port != "CONTROLLER":
                            if not out_port in self.ofi2pp:
                                return -1, "Error: Output port " + out_port + " is not in switch port list"

                            if translate_of_ports:
                                out_port = self.ofi2pp[out_port]

                        actions.append( ('out', out_port) )

                    if instruction['type'] == "L2MODIFICATION" and instruction['subtype'] == "VLAN_POP":
                        actions.append( ('vlan', 'None') )
                    if instruction['type'] == "L2MODIFICATION" and instruction['subtype'] == "VLAN_ID":
                        actions.append( ('vlan', instruction['vlanId']) )

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

            return 0, rules

        except (requests.exceptions.RequestException, 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)
            return -1, error_text

    def del_flow(self, flow_name):
        ''' Delete an existing rule
            Params: flow_name, this is the rule name
            Return
                0, None if ok
                -1, text_error if fails
        '''

        try:
            self.headers['content-type'] = None
            of_response = requests.delete(self.url + "flows/" + self.id + "/" + flow_name, headers=self.headers)
            error_text = "Openflow response %d: %s" % (of_response.status_code, of_response.text)

            if of_response.status_code != 204:
                self.logger.warning("del_flow " + error_text)
                return -1 , error_text
            self.logger.debug("del_flow OK " + error_text)
            return 0, None

        except requests.exceptions.RequestException as e:
            error_text = type(e).__name__ + ": " + str(e)
            self.logger.error("del_flow " + error_text)
            return -1, error_text

    def new_flow(self, data):
        ''' Insert a new static rule
            Params: 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
                0, None if ok
                -1, text_error if fails
        '''

        if len(self.pp2ofi) == 0:
            r,c = self.obtain_port_correspondence()
            if r<0:
                return r,c
        try:
            # Build the dictionary with the flow rule information for ONOS
            flow = dict()
            #flow['id'] = data['name']
            flow['tableId'] = 0
            flow['priority'] = data.get('priority')
            flow['timeout'] = 0
            flow['isPermanent'] = "true"
            flow['appId'] = 10 # FIXME We should create an appId for OSM
            flow['selector'] = dict()
            flow['selector']['criteria'] = list()

            # Flow rule matching criteria
            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)
                return -1, error_text

            ingress_port_criteria = dict()
            ingress_port_criteria['type'] = "IN_PORT"
            ingress_port_criteria['port'] = self.pp2ofi[data['ingress_port']]
            flow['selector']['criteria'].append(ingress_port_criteria)

            if 'dst_mac' in data:
                dst_mac_criteria = dict()
                dst_mac_criteria["type"] = "ETH_DST"
                dst_mac_criteria["mac"] = data['dst_mac']
                flow['selector']['criteria'].append(dst_mac_criteria)

            if data.get('vlan_id'):
                vlan_criteria = dict()
                vlan_criteria["type"] = "VLAN_VID"
                vlan_criteria["vlanId"] = int(data['vlan_id'])
                flow['selector']['criteria'].append(vlan_criteria)

            # Flow rule treatment
            flow['treatment'] = dict()
            flow['treatment']['instructions'] = list()
            flow['treatment']['deferred'] = list()

            for action in data['actions']:
                new_action = dict()
                if  action[0] == "vlan":
                    new_action['type'] = "L2MODIFICATION"
                    if action[1] == None:
                        new_action['subtype'] = "VLAN_POP"
                    else:
                        new_action['subtype'] = "VLAN_ID"
                        new_action['vlanId'] = int(action[1])
                elif action[0] == 'out':
                    new_action['type'] = "OUTPUT"
                    if not action[1] in self.pp2ofi:
                        error_msj = 'Port '+ action[1] + ' is not present in the switch'
                        return -1, error_msj
                    new_action['port'] = self.pp2ofi[action[1]]
                else:
                    error_msj = "Unknown item '%s' in action list" % action[0]
                    self.logger.error("new_flow " + error_msj)
                    return -1, error_msj

                flow['treatment']['instructions'].append(new_action)

            self.headers['content-type'] = 'application/json'
            path = self.url + "flows/" + self.id
            of_response = requests.post(path, headers=self.headers, data=json.dumps(flow) )

            error_text = "Openflow response %d: %s" % (of_response.status_code, of_response.text)
            if of_response.status_code != 201:
                self.logger.warning("new_flow " + error_text)
                return -1 , error_text


            flowId = of_response.headers['location'][path.__len__() + 1:]

            data['name'] = flowId

            self.logger.debug("new_flow OK " + error_text)
            return 0, None

        except requests.exceptions.RequestException as e:
            error_text = type(e).__name__ + ": " + str(e)
            self.logger.error("new_flow " + error_text)
            return -1, error_text

    def clear_all_flows(self):
        ''' Delete all existing rules
            Return:
                0, None if ok
                -1, text_error if fails
        '''           
        try:
            c, rules = self.get_of_rules(True)
            if c < 0:
                return -1, "Error retrieving the flows"

            for rule in rules:
                self.del_flow(rule)

            self.logger.debug("clear_all_flows OK ")
            return 0, None

        except requests.exceptions.RequestException as e:
            error_text = type(e).__name__ + ": " + str(e)
            self.logger.error("clear_all_flows " + error_text)
            return -1, error_text


