#!/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
