#!/usr/bin/env python

import time
import pexpect
import struct
import fcntl
import os
import sys
import signal
import sys
import re
import json
sys.path.append( "../" )
from drivers.common.clidriver import CLI


class QuaggaCliDriver( CLI ):

    def __init__( self ):
        super( CLI, self ).__init__()

    # TODO: simplify this method
    def connect( self, **connectargs ):
        for key in connectargs:
            vars( self )[ key ] = connectargs[ key ]

        self.name = self.options[ 'name' ]
        # self.handle = super( QuaggaCliDriver,self ).connect(
        # user_name=self.user_name, ip_address=self.ip_address,port=self.port,
        # pwd=self.pwd )
        self.handle = super(
            QuaggaCliDriver,
            self ).connect(
                user_name=self.user_name,
         ip_address="1.1.1.1",
         port=self.port,
         pwd=self.pwd )
        main.log.info(
            "connect parameters:" + str(
                self.user_name ) + ";" + str(
                    self.ip_address ) + ";" + str(
                 self.port ) + ";" + str(
                     self.pwd ) )

        if self.handle:
            # self.handle.expect( "",timeout=10 )
            # self.handle.expect( "\$",timeout=10 )
            self.handle.sendline( "telnet localhost 2605" )
            # self.handle.expect( "Password:", timeout=5 )
            self.handle.expect( "Password:" )
            self.handle.sendline( "hello" )
            # self.handle.expect( "bgpd", timeout=5 )
            self.handle.expect( "bgpd" )
            self.handle.sendline( "enable" )
            # self.handle.expect( "bgpd#", timeout=5 )
            self.handle.expect( "bgpd#" )
            return self.handle
        else:
            main.log.info( "NO HANDLE" )
            return main.FALSE

    def loginQuagga( self, ip_address ):
        self.name = self.options[ 'name' ]
        self.handle = super( QuaggaCliDriver, self ).connect(
            user_name=self.user_name, ip_address=ip_address,
            port=self.port, pwd=self.pwd )
        main.log.info( "connect parameters:" + str( self.user_name ) + ";"
                       + str( self.ip_address ) + ";" + str( self.port ) + ";" + str( self.pwd ) )

        if self.handle:
            # self.handle.expect( "" )
            # self.handle.expect( "\$" )
            self.handle.sendline( "telnet localhost 2605" )
            # self.handle.expect( "Password:", timeout=5 )
            self.handle.expect( "Password:" )
            self.handle.sendline( "hello" )
            # self.handle.expect( "bgpd", timeout=5 )
            self.handle.expect( "bgpd" )
            self.handle.sendline( "enable" )
            # self.handle.expect( "bgpd#", timeout=5 )
            self.handle.expect( "bgpd#" )
            main.log.info( "I in quagga on host " + str( ip_address ) )

            return self.handle
        else:
            main.log.info( "NO HANDLE" )
            return main.FALSE

    def enter_config( self, asn ):
        main.log.info( "I am in enter_config method!" )
        try:
            self.handle.sendline( "" )
            self.handle.expect( "bgpd#" )
        except:
            main.log.warn( "Probably not currently in enable mode!" )
            self.disconnect()
            return main.FALSE
        self.handle.sendline( "configure terminal" )
        self.handle.expect( "config", timeout=5 )
        routerAS = "router bgp " + str( asn )
        try:
            self.handle.sendline( routerAS )
            self.handle.expect( "config-router", timeout=5 )
            return main.TRUE
        except:
            return main.FALSE

    def generate_prefixes( self, net, numRoutes ):
        main.log.info( "I am in generate_prefixes method!" )

        # each IP prefix will be composed by "net" + "." + m + "." + n + "." + x
        # the length of each IP prefix is 24
        routes = []
        routes_gen = 0
        m = numRoutes / 256
        n = numRoutes % 256

        for i in range( 0, m ):
            for j in range( 0, 256 ):
                network = str(
                    net ) + "." + str(
                        i ) + "." + str(
                            j ) + ".0/24"
                routes.append( network )
                routes_gen = routes_gen + 1

        for j in range( 0, n ):
            network = str( net ) + "." + str( m ) + "." + str( j ) + ".0/24"
            routes.append( network )
            routes_gen = routes_gen + 1

        if routes_gen == numRoutes:
            main.log.info( "Successfully generated " + str( numRoutes )
                           + " prefixes!" )
            return routes
        return main.FALSE

    # This method generates a multiple to single point intent(
    # MultiPointToSinglePointIntent ) for a given route
    def generate_expected_singleRouteIntent( self, prefix, nextHop, nextHopMac, sdnip_data ):

        ingress = []
        egress = ""
        for peer in sdnip_data[ 'bgpPeers' ]:
            if peer[ 'ipAddress' ] == nextHop:
                egress = "of:" + str( peer[ 'attachmentDpid' ] ).replace( ":", "" ) + ":" + str( peer[ 'attachmentPort' ] )
            else:
                ingress.append( "of:" +  \
                         str( peer[ 'attachmentDpid' ] ).replace( ":",
                         "" ) + ":" + str( peer[ 'attachmentPort' ] ) )

        selector = "ETH_TYPE{ethType=800},IPV4_DST{ip=" + prefix + "}"
        treatment = "[ETH_DST{mac=" + str( nextHopMac ) + "}]"

        intent = egress + "/" + \
            str( sorted( ingress ) ) + "/" + selector + "/" + treatment
        return intent

    def generate_expected_onePeerRouteIntents( self, prefixes, nextHop, nextHopMac, sdnip_json_file_path ):
        intents = []
        sdnip_json_file = open( sdnip_json_file_path ).read()

        sdnip_data = json.loads( sdnip_json_file )

        for prefix in prefixes:
            intents.append(
                self.generate_expected_singleRouteIntent(
                    prefix,
                    nextHop,
                    nextHopMac,
                    sdnip_data ) )
        return sorted( intents )

    # TODO
    # This method generates all expected route intents for all BGP peers
    def generate_expected_routeIntents( self ):
        intents = []
        return intents

    # This method extracts all actual routes from ONOS CLI
    def extract_actual_routes( self, get_routes_result ):
        routes_json_obj = json.loads( get_routes_result )

        allRoutes_actual = []
        for route in routes_json_obj:
            if route[ 'prefix' ] == '172.16.10.0/24':
                continue
            allRoutes_actual.append(
                route[ 'prefix' ] + "/" + route[ 'nextHop' ] )

        return sorted( allRoutes_actual )

    # This method extracts all actual route intents from ONOS CLI
    def extract_actual_routeIntents( self, get_intents_result ):
        intents = []
        # TODO: delete the line below when change to Mininet demo script
        # get_intents_result=open( "../tests/SdnIpTest/intents.json" ).read()
        intents_json_obj = json.loads( get_intents_result )

        for intent in intents_json_obj:
            if intent[ 'appId' ] != "org.onosproject.sdnip":
                continue
            if intent[ 'type' ] == "MultiPointToSinglePointIntent" and intent[ 'state' ] == 'INSTALLED':
                egress = str( intent[ 'egress' ][ 'device' ] ) + ":" + str(
                    intent[ 'egress' ][ 'port' ] )
                ingress = []
                for attachmentPoint in intent[ 'ingress' ]:
                    ingress.append(
                        str( attachmentPoint[ 'device' ] ) + ":" + str( attachmentPoint[ 'port' ] ) )

                selector = intent[ 'selector' ].replace(
                    "[", "" ).replace( "]", "" ).replace( " ", "" )
                if str( selector ).startswith( "IPV4" ):
                    str1, str2 = str( selector ).split( "," )
                    selector = str2 + "," + str1

                intent = egress + "/" + \
                    str( sorted( ingress ) ) + "/" + \
                        selector + "/" + intent[ 'treatment' ]
                intents.append( intent )
        return sorted( intents )

    # This method extracts all actual BGP intents from ONOS CLI
    def extract_actual_bgpIntents( self, get_intents_result ):
        intents = []
        # TODO: delete the line below when change to Mininet demo script
        # get_intents_result=open( "../tests/SdnIpTest/intents.json" ).read()
        intents_json_obj = json.loads( get_intents_result )

        for intent in intents_json_obj:
            if intent[ 'appId' ] != "org.onosproject.sdnip":
                continue
            if intent[ 'type' ] == "PointToPointIntent" and "protocol=6" in str( intent[ 'selector' ] ):
                ingress = str( intent[ 'ingress' ][ 'device' ] ) + ":" + str(
                    intent[ 'ingress' ][ 'port' ] )
                egress = str( intent[ 'egress' ][ 'device' ] ) + ":" + str(
                    intent[ 'egress' ][ 'port' ] )
                selector = str(
                    intent[ 'selector' ] ).replace( " ", "" ).replace( "[", "" ).replace( "]", "" ).split( "," )
                intent = ingress + "/" + egress + \
                    "/" + str( sorted( selector ) )
                intents.append( intent )

        return sorted( intents )

    # This method generates a single point to single point intent(
    # PointToPointIntent ) for BGP path
    def generate_expected_bgpIntents( self, sdnip_json_file_path ):
        from operator import eq

        sdnip_json_file = open( sdnip_json_file_path ).read()
        sdnip_data = json.loads( sdnip_json_file )

        intents = []
        bgpPeerAttachmentPoint = ""
        bgpSpeakerAttachmentPoint = "of:" + str(
            sdnip_data[ 'bgpSpeakers' ][ 0 ][ 'attachmentDpid' ] ).replace( ":",
                                                                            "" ) + ":" + str( sdnip_data[ 'bgpSpeakers' ][ 0 ][ 'attachmentPort' ] )
        for peer in sdnip_data[ 'bgpPeers' ]:
            bgpPeerAttachmentPoint = "of:" + str(
                peer[ 'attachmentDpid' ] ).replace( ":", "" ) + ":" + str( peer[ 'attachmentPort' ] )
            # find out the BGP speaker IP address for this BGP peer
            bgpSpeakerIpAddress = ""
            for interfaceAddress in sdnip_data[ 'bgpSpeakers' ][ 0 ][ 'interfaceAddresses' ]:
                # if eq( interfaceAddress[ 'interfaceDpid' ],sdnip_data[
                # 'bgpSpeakers' ][ 0 ][ 'attachmentDpid' ] ) and eq(
                # interfaceAddress[ 'interfacePort' ], sdnip_data[
                # 'bgpSpeakers' ][ 0 ][ 'attachmentPort' ] ):
                if eq( interfaceAddress[ 'interfaceDpid' ], peer[ 'attachmentDpid' ] ) and eq( interfaceAddress[ 'interfacePort' ], peer[ 'attachmentPort' ] ):
                    bgpSpeakerIpAddress = interfaceAddress[ 'ipAddress' ]
                    break
                else:
                    continue

            # from bgpSpeakerAttachmentPoint to bgpPeerAttachmentPoint
            # direction
            selector_str = "IPV4_SRC{ip=" + bgpSpeakerIpAddress + "/32}," + "IPV4_DST{ip=" + peer[
                'ipAddress' ] + "/32}," + "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800}, TCP_DST{tcpPort=179}"
            selector = selector_str.replace( " ", "" ).replace(
                "[", "" ).replace( "]", "" ).split( "," )
            intent = bgpSpeakerAttachmentPoint + "/" + \
                bgpPeerAttachmentPoint + "/" + str( sorted( selector ) )
            intents.append( intent )

            selector_str = "IPV4_SRC{ip=" + bgpSpeakerIpAddress + "/32}," + "IPV4_DST{ip=" + peer[
                'ipAddress' ] + "/32}," + "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800}, TCP_SRC{tcpPort=179}"
            selector = selector_str.replace( " ", "" ).replace(
                "[", "" ).replace( "]", "" ).split( "," )
            intent = bgpSpeakerAttachmentPoint + "/" + \
                bgpPeerAttachmentPoint + "/" + str( sorted( selector ) )
            intents.append( intent )

            # from bgpPeerAttachmentPoint to bgpSpeakerAttachmentPoint
            # direction
            selector_str = "IPV4_SRC{ip=" + peer[ 'ipAddress' ] + "/32}," + "IPV4_DST{ip=" + bgpSpeakerIpAddress + "/32}," + \
                "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800}, TCP_DST{tcpPort=179}"
            selector = selector_str.replace( " ", "" ).replace(
                "[", "" ).replace( "]", "" ).split( "," )
            intent = bgpPeerAttachmentPoint + "/" + \
                bgpSpeakerAttachmentPoint + "/" + str( sorted( selector ) )
            intents.append( intent )

            selector_str = "IPV4_SRC{ip=" + peer[ 'ipAddress' ] + "/32}," + "IPV4_DST{ip=" + bgpSpeakerIpAddress + "/32}," + \
                "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800}, TCP_SRC{tcpPort=179}"
            selector = selector_str.replace( " ", "" ).replace(
                "[", "" ).replace( "]", "" ).split( "," )
            intent = bgpPeerAttachmentPoint + "/" + \
                bgpSpeakerAttachmentPoint + "/" + str( sorted( selector ) )
            intents.append( intent )

        return sorted( intents )

    def add_routes( self, routes, routeRate ):
        main.log.info( "I am in add_routes method!" )

        routes_added = 0
        try:
            self.handle.sendline( "" )
            # self.handle.expect( "config-router" )
            self.handle.expect( "config-router", timeout=5 )
        except:
            main.log.warn( "Probably not in config-router mode!" )
            self.disconnect()
        main.log.info( "Start to add routes" )

        for i in range( 0, len( routes ) ):
            routeCmd = "network " + routes[ i ]
            try:
                self.handle.sendline( routeCmd )
                self.handle.expect( "bgpd", timeout=5 )
            except:
                main.log.warn( "Failed to add route" )
                self.disconnect()
            waitTimer = 1.00 / routeRate
            time.sleep( waitTimer )
        if routes_added == len( routes ):
            main.log.info( "Finished adding routes" )
            return main.TRUE
        return main.FALSE

    def delete_routes( self, routes, routeRate ):
        main.log.info( "I am in delete_routes method!" )

        routes_added = 0
        try:
            self.handle.sendline( "" )
            # self.handle.expect( "config-router" )
            self.handle.expect( "config-router", timeout=5 )
        except:
            main.log.warn( "Probably not in config-router mode!" )
            self.disconnect()
        main.log.info( "Start to delete routes" )

        for i in range( 0, len( routes ) ):
            routeCmd = "no network " + routes[ i ]
            try:
                self.handle.sendline( routeCmd )
                self.handle.expect( "bgpd", timeout=5 )
            except:
                main.log.warn( "Failed to add route" )
                self.disconnect()
            waitTimer = 1.00 / routeRate
            time.sleep( waitTimer )
        if routes_added == len( routes ):
            main.log.info( "Finished deleting routes" )
            return main.TRUE
        return main.FALSE

    def ping_test( self, ip_address, ping_test_file, ping_test_result_file ):
        main.log.info( "Start the ping test on host:" + str( ip_address ) )

        self.name = self.options[ 'name' ]
        self.handle = super( QuaggaCliDriver, self ).connect(
            user_name=self.user_name, ip_address=ip_address,
            port=self.port, pwd=self.pwd )
        main.log.info( "connect parameters:" + str( self.user_name ) + ";"
                       + str( self.ip_address ) + ";" + str( self.port ) + ";" + str( self.pwd ) )

        if self.handle:
            # self.handle.expect( "" )
            # self.handle.expect( "\$" )
            main.log.info( "I in host " + str( ip_address ) )
            main.log.info(
                ping_test_file +
                " > " +
                ping_test_result_file +
                " &" )
            self.handle.sendline(
                ping_test_file +
                " > " +
                ping_test_result_file +
                " &" )
            self.handle.expect( "\$", timeout=60 )
            handle = self.handle.before

            return handle
        else:
            main.log.info( "NO HANDLE" )
            return main.FALSE

    # Please use the generate_routes plus add_routes instead of this one
    def add_route( self, net, numRoutes, routeRate ):
        try:
            self.handle.sendline( "" )
            self.handle.expect( "config-router" )
        except:
            main.log.warn( "Probably not in config-router mode!" )
            self.disconnect()
        main.log.info( "Adding Routes" )
        j = 0
        k = 0
        while numRoutes > 255:
            numRoutes = numRoutes - 255
            j = j + 1
        k = numRoutes % 254
        routes_added = 0
        if numRoutes > 255:
            numRoutes = 255
        for m in range( 1, j + 1 ):
            for n in range( 1, numRoutes + 1 ):
                network = str( net ) + "." + str( m ) + "." + str( n ) + ".0/24"
                routeCmd = "network " + network
                try:
                    self.handle.sendline( routeCmd )
                    self.handle.expect( "bgpd" )
                except:
                    main.log.warn( "failed to add route" )
                    self.disconnect()
                waitTimer = 1.00 / routeRate
                time.sleep( waitTimer )
                routes_added = routes_added + 1
        for d in range( j + 1, j + 2 ):
            for e in range( 1, k + 1 ):
                network = str(
                    net ) + "." + str(
                        d ) + "." + str(
                            e ) + ".0/24"
                routeCmd = "network " + network
                try:
                    self.handle.sendline( routeCmd )
                    self.handle.expect( "bgpd" )
                except:
                    main.log.warn( "failed to add route" )
                    self.disconnect
                waitTimer = 1.00 / routeRate
                time.sleep( waitTimer )
                routes_added = routes_added + 1
        if routes_added == numRoutes:
            return main.TRUE
        return main.FALSE

    def del_route( self, net, numRoutes, routeRate ):
        try:
            self.handle.sendline( "" )
            self.handle.expect( "config-router" )
        except:
            main.log.warn( "Probably not in config-router mode!" )
            self.disconnect()
        main.log.info( "Deleting Routes" )
        j = 0
        k = 0
        while numRoutes > 255:
            numRoutes = numRoutes - 255
            j = j + 1
        k = numRoutes % 254
        routes_deleted = 0
        if numRoutes > 255:
            numRoutes = 255
        for m in range( 1, j + 1 ):
            for n in range( 1, numRoutes + 1 ):
                network = str( net ) + "." + str( m ) + "." + str( n ) + ".0/24"
                routeCmd = "no network " + network
                try:
                    self.handle.sendline( routeCmd )
                    self.handle.expect( "bgpd" )
                except:
                    main.log.warn( "Failed to delete route" )
                    self.disconnect()
                waitTimer = 1.00 / routeRate
                time.sleep( waitTimer )
                routes_deleted = routes_deleted + 1
        for d in range( j + 1, j + 2 ):
            for e in range( 1, k + 1 ):
                network = str( net ) + "." + str( d ) + "." + str( e ) + ".0/24"
                routeCmd = "no network " + network
                try:
                    self.handle.sendline( routeCmd )
                    self.handle.expect( "bgpd" )
                except:
                    main.log.warn( "Failed to delete route" )
                    self.disconnect()
                waitTimer = 1.00 / routeRate
                time.sleep( waitTimer )
                routes_deleted = routes_deleted + 1
        if routes_deleted == numRoutes:
            return main.TRUE
        return main.FALSE

    def check_routes( self, brand, ip, user, pw ):
        def pronto( ip, user, passwd ):
            print "Connecting to Pronto switch"
            child = pexpect.spawn( "telnet " + ip )
            i = child.expect( [ "login:", "CLI#", pexpect.TIMEOUT ] )
            if i == 0:
                print "Username and password required. Passing login info."
                child.sendline( user )
                child.expect( "Password:" )
                child.sendline( passwd )
                child.expect( "CLI#" )
            print "Logged in, getting flowtable."
            child.sendline( "flowtable brief" )
            for t in range( 9 ):
                t2 = 9 - t
                print "\r" + str( t2 )
                sys.stdout.write( "\033[F" )
                time.sleep( 1 )
            print "Scanning flowtable"
            child.expect( "Flow table show" )
            count = 0
            while True:
                i = child.expect(
                    [ '17\d\.\d{1,3}\.\d{1,3}\.\d{1,3}',
                                'CLI#',
                                pexpect.TIMEOUT ] )
                if i == 0:
                    count = count + 1
                elif i == 1:
                    print "Pronto flows: " + str( count ) + "\nDone\n"
                    break
                else:
                    break

        def cisco( ip, user, passwd ):
            print "Establishing Cisco switch connection"
            child = pexpect.spawn( "ssh " + user + "@" + ip )
            i = child.expect( [ "Password:", "CLI#", pexpect.TIMEOUT ] )
            if i == 0:
                print "Password required. Passing now."
                child.sendline( passwd )
                child.expect( "#" )
            print "Logged in. Retrieving flow table then counting flows."
            child.sendline( "show openflow switch all flows all" )
            child.expect( "Logical Openflow Switch" )
            print "Flow table retrieved. Counting flows"
            count = 0
            while True:
                i = child.expect( [ "nw_src=17", "#", pexpect.TIMEOUT ] )
                if i == 0:
                    count = count + 1
                elif i == 1:
                    print "Cisco flows: " + str( count ) + "\nDone\n"
                    break
                else:
                    break
            if brand == "pronto" or brand == "PRONTO":
                pronto( ip, user, passwd )
            # elif brand  == "cisco" or brand == "CISCO":
            #    cisco( ip,user,passwd )

    def disconnect( self ):
        """
        Called when Test is complete to disconnect the Quagga handle.
        """
        response = ''
        try:
            self.handle.close()
        except:
            main.log.error( "Connection failed to the host" )
            response = main.FALSE
        return response

