#!/usr/bin/env python
"""
Created on 26-Mar-2013
Copyright 2013 Open Networking Foundation (ONF)

Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>

author:: Anil Kumar ( anilkumar.s@paxterrasolutions.com )


    TestON is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 2 of the License, or
    ( at your option ) any later version.

    TestON is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with TestON.  If not, see <http://www.gnu.org/licenses/>.


FlowVisorDriver is the basic driver which will handle the Mininet functions
"""
import re
import sys
from drivers.common.cli.emulatordriver import Emulator


class FlowVisorDriver( Emulator ):

    """
        FlowVisorDriver is the basic driver which will handle the Mininet functions
    """
    def __init__( self ):
        super( FlowVisorDriver, self ).__init__()
        self.handle = self
        self.wrapped = sys.modules[ __name__ ]

    def connect( self, **connectargs ):
        #,user_name, ip_address, pwd,options ):
        # Here the main is the TestON instance after creating all the log
        # handles.
        for key in connectargs:
            vars( self )[ key ] = connectargs[ key ]

        self.name = self.options[ 'name' ]
        self.handle = super(
            FlowVisorDriver,
            self ).connect(
            user_name=self.user_name,
            ip_address=self.ip_address,
            port=None,
            pwd=self.pwd )

        self.ssh_handle = self.handle

        # Copying the readme file to process the
        if self.handle:
            self.execute( cmd='\r', prompt=self.prompt, timeout=10 )
            self.options[ 'path' ] = '/home/openflow/flowvisor/scripts/'
            #self.handle.logfile = sys.stdout
            self.execute(
                cmd='cd ' +
                self.options[ 'path' ],
                prompt=self.prompt,
                timeout=10 )
            main.log.info( "Starting FlowVisor " )

            response = self.execute(
                cmd='./flowvisor.sh &',
                prompt='---\sSetting\slogging\slevel\sto\sNOTE',
                timeout=10 )

            pattern = '\d+'

            process_id_search = re.search( "\[\d+\]\s+(\d+)", str( response ) )
            self.fvprocess_id = "None"
            if process_id_search:
                self.fvprocess_id = process_id_search.group( 1 )

            utilities.assert_matches(
                expect=pattern,
                actual=response,
                onpass="FlowVisor Started Successfully : Proceess Id :" +
                self.fvprocess_id,
                onfail="Failed to start FlowVisor" )
            main.log.info( response )
            #import time
            # time.sleep( 10 )
            #response = self.execute( cmd='./start_visualizer.sh & \r',prompt=self.prompt,timeout=10 )

            return main.TRUE
        else:
            main.log.error(
                "Connection failed to the host " +
                self.user_name +
                "@" +
                self.ip_address )
            main.log.error( "Failed to connect to the FlowVisor" )
            return main.FALSE

    def removeFlowSpace( self, id ):
        if id == "all":
            flow_space = self.listFlowSpace()
            flow_ids = re.findall( "\,id=\[(\d+)\]", flow_space )
            for id in flow_ids:
                self.removeFlowSpace( id )
        else:
            self.execute( cmd="clear", prompt=self.prompt, timeout=10 )
            self.execute(
                cmd="./fvctl.sh removeFlowSpace " +
                id,
                prompt="passwd:",
                timeout=10 )
            self.execute( cmd="\n", prompt=self.prompt, timeout=10 )
            main.log.info( "Removed flowSpace which is having id :" + id )

        return main.TRUE

    def addFlowSpace( self, **flowspace_args ):
        temp_string = None
        for key in flowspace_args:
            if temp_string:
                temp_string = temp_string + ',' + \
                    key + '=' + flowspace_args[ key ]
            else:
                temp_string = ''
                temp_string = temp_string + key + '=' + flowspace_args[ key ]

        src_search = re.search( 'dl_src', temp_string )
        if src_search:
            flowspace = "any 100 dl_type=0x806,nw_proto=6," + \
                temp_string + " Slice:SSH=4"
        else:
            flowspace = "any 100 dl_type=0x800,nw_proto=6," + \
                temp_string + " Slice:SSH=4"

        """
        try :
            if self.dl_src and self.nw_dst:
                flowspace = "any 100 dl_type=0x806,dl_src="+self.dl_src+",nw_dst="+self.nw_dst+" Slice:"+self.Slice+"=4"
        except Exception:
            try :
                if self.nw_src and self.tp_dst:
                    flowspace = "any 100 dl_type=0x800,nw_proto=6,nw_src="+self.nw_src+",tp_dst="+self.tp_dst+" Slice:"+self.Slice+"=4"
            except Exception:
                try :
                    if self.nw_src and self.tp_src:
                        flowspace = "any 100 dl_type=0x800,nw_proto=6,nw_src="+self.nw_src+",tp_src="+self.tp_dst+" Slice:"+self.Slice+"=4"
                except Exception:
                    main.log.error( "Please specify flowspace properly" )
        """
        # self.execute( cmd="clear",prompt=self.prompt,timeout=10 )
        self.execute(
            cmd="./fvctl.sh addFlowSpace " +
            flowspace,
            prompt="passwd:",
            timeout=10 )
        self.execute( cmd="\n", prompt=self.prompt, timeout=10 )
        sucess_match = re.search( "success\:\s+(\d+)", main.last_response )
        if sucess_match:
            main.log.info(
                "Added flow Space and id is " +
                sucess_match.group( 1 ) )
            return main.TRUE
        else:
            return main.FALSE

    def listFlowSpace( self ):
        self.execute( cmd="clear", prompt=self.prompt, timeout=10 )
        self.execute(
            cmd="./fvctl.sh listFlowSpace ",
            prompt="passwd:",
            timeout=10 )
        self.execute( cmd="\n", prompt=self.prompt, timeout=10 )
        flow_space = main.last_response
        flow_space = self.remove_contol_chars( flow_space )
        flow_space = re.sub(
            "rule\s(\d+)\:",
            "\nrule " +
            r'\1' +
            ":",
            flow_space )
        main.log.info( flow_space )

        return flow_space

    def listDevices( self ):
        # self.execute( cmd="clear",prompt=self.prompt,timeout=10 )
        #self.execute( cmd="./fvctl.sh listDevices ",prompt="passwd:",timeout=10 )
        # self.execute( cmd="\n",prompt=self.prompt,timeout=10 )
        devices_list = ''
        last_response = re.findall(
            "(Device\s\d+\:\s((\d|[a-z])(\d|[a-z])\:)+(\d|[a-z])(\d|[a-z]))",
            main.last_response )

        for resp in last_response:
            devices_match = re.search(
                "(Device\s\d+\:\s((\d|[a-z])(\d|[a-z])\:)+(\d|[a-z])(\d|[a-z]))",
                str( resp ) )
            if devices_match:
                devices_list = devices_list + devices_match.group( 0 ) + "\n"
        devices_list = "Device 0: 00:00:00:00:00:00:00:02 \n Device 1: 00:00:00:00:00:00:00:03"
        main.log.info( "List of Devices \n" + devices_list )

        return main.TRUE

    def disconnect( self ):

        response = ''
        main.log.info( "Stopping the FlowVisor" )
        if self.handle:
            self.handle.sendline( "kill -9 " + str( self.fvprocess_id ) )
        else:
            main.log.error( "Connection failed to the host" )
            response = main.FALSE
        return response
