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

##
# Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U.
# This file is part of openmano
# 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
##

'''
This program is useful to interact directly with Openflow Controllers
to clear rules, add and delete rules, list rules, etc.
'''

__author__="Gerardo Garcia, Alfonso Tierno, Pablo Montes"
__date__ ="$09-oct-2014 09:09:48$"

#import time
import os
import sys
import argparse
import argcomplete
import imp
import yaml
import requests
import logging
from openflow_thread import change_db2of, FlowBadFormat

def of_switches(args):
    r,c = ofconnector.get_of_switches()
    if r<0:
        print c
        return r
    else: 
        for s in c:
            print " %s %s" % (s[0], s[1])
    return 0

def of_list(args):
    r,c = ofconnector.get_of_rules(not args.no_translate)
    if r<0:
        print c
        return r
    if args.verbose > 0:
        print yaml.safe_dump(c, indent=4, default_flow_style=False)
        return 0

    print "       switch           priority        name                             ingress_port    dst_mac       vlan_id  actions"
    for name,rule in c.iteritems():
        action_list=[]
        for action in rule["actions"]:
            action_list.append(action[0]+"="+str(action[1]))
        if "vlan_id" in rule:
            vlan=str(rule["vlan_id"])
        else:
            vlan="any"
        print "%s  %s  %s  %s  %s  %s  %s" % \
            (rule["switch"], str(rule["priority"]).ljust(6), name.ljust(40), rule["ingress_port"].ljust(8), \
            rule.get("dst_mac","any").ljust(18), vlan.ljust(4), ",".join(action_list) )
    return 0

def of_clear(args):
    if not args.force:
        r = raw_input("Clear all Openflow rules (y/N)? ")
        if  not (len(r)>0  and r[0].lower()=="y"):
            return 0
    r,c = ofconnector.clear_all_flows()
    if r<0:
        print c
        return r
    return 0

def of_port_list(args):
    r,c = ofconnector.obtain_port_correspondence()
    if r<0:
        print c
        return r
    yaml.safe_dump({"ports": c}, sys.stdout, indent=2, default_flow_style=False)

#def of_dump(args):
#    args.verbose = 3
#    args.no_translate=False
#    of_list(args)
    return 0

def of_reinstall(args):
    try:
        URLrequest = "http://%s:%s/openvim/networks/all/openflow" %(vim_host, vim_admin_port)
        print URLrequest
        openvim_response = requests.put(URLrequest)
        print openvim_response.text
        return 0
    except requests.exceptions.RequestException as e:
        print " Exception GET at '"+URLrequest+"' " + str(e)
        return -1

def of_install(args):
    line_number=1
    try:
        f = open(args.file, "r")
        text = f.read()
        f.close()
        lines=text.split("\n")
        heads=lines[0].split()

        for line in lines[1:]:
            line_number += 1
            rule={}
            items= line.split()
            if len(items)==0 or items[0][0]=="#": #empty line or commented
                continue
            for i in range(0,len(items)):
                rule[ heads[i] ] = items[i]
            if rule["vlan_id"] == "any":
                del rule["vlan_id"]
            if rule["dst_mac"] == "any":
                del rule["dst_mac"]
            if 'priority' in rule and (rule['priority']==None or rule['priority']=="None" ):
                del rule['priority']
            try:
                change_db2of(rule)
            except FlowBadFormat as e:
                print "Format error at line %d:  %s" % (line_number, str(e))
                continue
            r,c = ofconnector.new_flow(rule)
            if r<0:
                error="ERROR: "+c
            else:
                error="OK"
            print "%s  %s  %s  input=%s  dst_mac=%s  vlan_id=%s  %s" % \
                    (rule["switch"], str(rule.get("priority")).ljust(6), rule["name"].ljust(20), rule["ingress_port"].ljust(3), \
                     rule.get("dst_mac","any").ljust(18), rule.get("vlan_id","any").ljust(4), error )
        return 0
    except IOError as e:
        print " Error opening file '" + args.file + "': " + e.args[1]
        return -1
    except yaml.YAMLError as exc:
        error_pos = ""
        if hasattr(exc, 'problem_mark'):
            mark = exc.problem_mark
            error_pos = " at position: (%s:%s)" % (mark.line+1, mark.column+1)
        print " Error yaml/json format error at " + error_pos
        return -1

def of_add(args):
    if args.act==None and args.actions==None:
        print "openflow add: error: one of the arguments --actions or [--setvlan,--stripvlan],--out is required"
        return -1
    elif args.act!=None and args.actions!=None:
        print "openflow add: error: Use either --actions option or [--setvlan,--stripvlan],--out options; but not both"
        return -1
    
    rule={"name":args.name, "priority":args.priority,
          "ingress_port": args.inport
        }
    if args.matchvlan:
        rule["vlan_id"] = args.matchvlan
    if args.matchmac:
        rule["dst_mac"] = args.matchmac

    if args.actions:
        rule["actions"] = args.actions
        try:
            change_db2of(rule)
        except FlowBadFormat as e:
            print "Format error at --actions: '%s' Expected 'vlan=<None/vlan_id>,out=<egress_port>,...'" % str(e)
            return -1
    elif args.act:
        rule["actions"]=[]
        error_msj = "openflow add: error: --setvlan,--stripvlan options must be followed by an --out option"
        previous_option_vlan=False # indicates if the previous option was a set or strip vlan to avoid consecutive ones and to force an out options afterwards
        for action in args.act:
            if action==None or type(action)==int:
                if previous_option_vlan: #consecutive vlan options
                    print error_msj
                    return -1
                previous_option_vlan=True
                rule["actions"].append( ("vlan", action) )
            else:
                previous_option_vlan=False
                rule["actions"].append( ("out", action) ) 
        if previous_option_vlan:
            print error_msj
            return -1
    #print rule
    #return

    r,c = ofconnector.new_flow(rule)
    if r<0:
        print c
        return -1
    if args.print_id:
        print rule["name"]
    return 0

def of_delete(args):
    if not args.force:
        r = raw_input("Clear rule %s (y/N)? " %(args.name))
        if  not (len(r)>0  and r[0].lower()=="y"):
            return 0
    r,c = ofconnector.del_flow(args.name)
    if r<0:
        print c
        return -1
    return 0

def config(args):
    print "OPENVIM_HOST: %s" %(vim_host)
    print "OPENVIM_ADMIN_PORT: %s" %(vim_admin_port)
    print "OF_CONTROLLER_TYPE: %s" %(of_controller_type)
    if of_controller_module or (of_controller_type!="floodlight" and of_controller_type!="opendaylight"):
        print "OF_CONTROLLER_MODULE: %s" %(of_controller_module)
    print "OF_CONTROLLER_USER: %s" %(of_controller_user)
    print "OF_CONTROLLER_PASSWORD: %s" %(of_controller_password)
    #print "OF_CONTROLLER_VERSION: %s" %(of_controller_version)
    print "OF_CONTROLLER_IP: %s" %(of_controller_ip)
    print "OF_CONTROLLER_PORT: %s" %(of_controller_port)
    print "OF_CONTROLLER_DPID: %s" %(of_controller_dpid)
    return

version="0.8"
global vim_host
global vim_admin_port
global of_controller_type
global of_controller_user
global of_controller_password
global of_controller_ip
global of_controller_port
global of_controller_dpid
global of_controller_module
global ofconnector
   
if __name__=="__main__":
    #print "test_ofconnector version", version, "Jul 2015"
    #print "(c) Copyright Telefonica"
    
    vim_host = os.getenv('OPENVIM_HOST',"localhost")
    vim_admin_port = os.getenv('OPENVIM_ADMIN_PORT',"8085")
    of_controller_type = os.getenv('OF_CONTROLLER_TYPE',"floodlight")
    of_controller_user = os.getenv('OF_CONTROLLER_USER',None)
    of_controller_password = os.getenv('OF_CONTROLLER_PASSWORD',None)
    #of_controller_version = os.getenv('OF_CONTROLLER_VERSION',"0.90")
    of_controller_ip = os.getenv('OF_CONTROLLER_IP',"localhost")
    of_controller_port = os.getenv('OF_CONTROLLER_PORT',"7070")
    of_controller_dpid = os.getenv('OF_CONTROLLER_DPID','00:01:02:03:e4:05:e6:07')
    of_controller_module = os.getenv('OF_CONTROLLER_MODULE',None)
    
    main_parser = argparse.ArgumentParser(description='User program to interact with Openflow controller')
    main_parser.add_argument('--version', action='version', version='%(prog)s ' + version )
    
    #main_parser = argparse.ArgumentParser()
    subparsers = main_parser.add_subparsers(help='commands')
    
    config_parser = subparsers.add_parser('config', help="prints configuration values")
    config_parser.set_defaults(func=config)
    
    add_parser = subparsers.add_parser('add', help="adds an openflow rule")
    add_parser.add_argument('--verbose', '-v', action='count')
    add_parser.add_argument("name", action="store", help="name of the rule")
    add_parser.add_argument("--inport", required=True, action="store", type=str, help="match rule: ingress-port")
    add_parser.add_argument("--actions", action="store", type=str, help="action with the format: vlan=<None/vlan-id>,out=<egress-port>,...")
    add_parser.add_argument("--priority", action="store", type=int, help="rule priority")
    add_parser.add_argument("--matchmac", action="store", help="match rule: mac address")
    add_parser.add_argument("--matchvlan", action="store", type=int, help="match rule: vlan id")
    add_parser.add_argument("--stripvlan", action="append_const", dest="act", const=None, help="alternative to --actions. Use before --out to strip vlan")
    add_parser.add_argument("--setvlan", action="append", dest="act", type=int, help="alternative to --actions. Use before --out to set vlan")
    add_parser.add_argument("--out", action="append", dest="act", type=str, help="alternative to --actions. out=<egress-port> can be used several times")
    add_parser.add_argument('--debug', '-d', action='store_true', help="show debug information")
    add_parser.add_argument('--print-id', action='store_true', help="print the flow id after added")
    add_parser.set_defaults(func=of_add)
    
    delete_parser = subparsers.add_parser('delete', help="delete an openflow rule")
    delete_parser.add_argument('--verbose', '-v', action='count')
    delete_parser.add_argument("-f", "--force", action="store_true", help="force deletion without asking")
    delete_parser.add_argument("name", action="store", help="name of the rule to be deleted")
    delete_parser.add_argument('--debug', '-d', action='store_true', help="show debug information")
    delete_parser.set_defaults(func=of_delete)
    
    switches_parser = subparsers.add_parser('switches', help="list all switches controlled by the OFC")
    switches_parser.add_argument('--verbose', '-v', action='count')
    switches_parser.add_argument('--debug', '-d', action='store_true', help="show debug information")
    switches_parser.set_defaults(func=of_switches)

    list_parser = subparsers.add_parser('list', help="list openflow rules")
    list_parser.add_argument('--verbose', '-v', action='count')
    list_parser.add_argument("--no-translate", "-n", action="store_true", help="Skip translation from openflow index to switch port name")
    list_parser.add_argument('--debug', '-d', action='store_true', help="show debug information")
    list_parser.set_defaults(func=of_list)

    #dump_parser = subparsers.add_parser('dump', help="dump openflow rules")
    #dump_parser.set_defaults(func=of_dump)
    
    clear_parser = subparsers.add_parser('clear', help="clear all openflow rules")
    clear_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
    clear_parser.add_argument('--debug', '-d', action='store_true', help="show debug information")
    clear_parser.set_defaults(func=of_clear)

    install_parser = subparsers.add_parser('install', help="install openflow rules from file")
    install_parser.add_argument("file", action="store", help="file with rules generated using 'openflow list > rules.txt'")
    install_parser.add_argument('--debug', '-d', action='store_true', help="show debug information")
    install_parser.set_defaults(func=of_install)

    reinstall_parser = subparsers.add_parser('reinstall', help="reinstall openflow rules from VIM rules")
    reinstall_parser.set_defaults(func=of_reinstall)
    reinstall_parser.add_argument('--debug', '-d', action='store_true', help="show debug information")

    portlist_parser = subparsers.add_parser('port-list', help="list the physical to openflow port correspondence")
    portlist_parser.set_defaults(func=of_port_list)
    portlist_parser.add_argument('--debug', '-d', action='store_true', help="show debug information")

    argcomplete.autocomplete(main_parser)
    
    args = main_parser.parse_args()
    module_info=None
    try:
        if args.func is not config:
            params={ "of_ip":   of_controller_ip,
                        "of_port": of_controller_port, 
                        "of_dpid": of_controller_dpid,
                        "of_user": of_controller_user,
                        "of_password": of_controller_password,
                }
            if "debug" in args and args.debug:
                streamformat = "%(asctime)s %(name)s %(levelname)s: %(message)s"
                logging.basicConfig(format=streamformat, level= logging.DEBUG)
                logger = logging.getLogger('vim')
                logger.setLevel(logging.DEBUG)
                params["of_debug"]="DEBUG"
            else:
                #logger = logging.getLogger('vim').addHandler(logging.NullHandler())
                #logger.setLevel(logging.CRITICAL)
                params["of_debug"]="CRITICAL"
            
            if of_controller_type=='opendaylight':
                module = "ODL"
            elif of_controller_module != None:
                module = of_controller_module
            else:
                module = of_controller_type
            module_info = imp.find_module(module)
            
            of_conn = imp.load_module("of_conn", *module_info)
            try:
                ofconnector = of_conn.OF_conn(params)
            except Exception as e: 
                print "Cannot open the Openflow controller '%s': %s" % (type(e).__name__, str(e))
                result = -1
                exit()
        result = args.func(args)
        if result == None:
            result = 0
            
        #for some reason it fails if call exit inside try instance. Need to call exit at the end !?
    except (IOError, ImportError) as e:
        print "Cannot open openflow controller module '%s'; %s: %s" % (module, type(e).__name__, str(e))
        result = -1
    #except Exception as e:
    #    print "Cannot open the Openflow controller '%s': %s" % (type(e).__name__, str(e))
    #    result = -1
    except requests.exceptions.ConnectionError as e:
        print "Cannot connect to server; %s: %s" % (type(e).__name__, str(e))
        result = -2
    except (KeyboardInterrupt):
        print 'Exiting openVIM'
        result = -3
    except (SystemExit):
        result = -4
    
    #close open file
    if module_info and module_info[0]:
        file.close(module_info[0])
    exit(result)
    


