
# Copyright 2016-present Ciena Corporation
#
# 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.
#
import unittest
from nose.tools import *
from scapy.all import *
from CordTestUtils import get_mac
from OnosCtrl import OnosCtrl
from OltConfig import OltConfig
from OnosFlowCtrl import OnosFlowCtrl
from onosclidriver import OnosCliDriver
from CordContainer import Container, Onos, Quagga
from CordTestServer import cord_test_onos_restart, cord_test_quagga_restart
from portmaps import g_subscriber_port_map
import threading
from threading import current_thread
import time
import os
import json
log.setLevel('INFO')


class proxyarp_exchange(unittest.TestCase):

    apps = ('org.onosproject.vrouter','org.onosproject.proxyarp')
    device_id = 'of:' + get_mac()
    device_dict = { "devices" : {
                "{}".format(device_id) : {
                    "basic" : {
                        "driver" : "softrouter"
                    }
                }
             },
          }
    test_path = os.path.dirname(os.path.realpath(__file__))
    onos_config_path = os.path.join(test_path, '..', 'setup/onos-config')
    GATEWAY = '192.168.10.50'
    INGRESS_PORT = 1
    EGRESS_PORT = 2
    MAX_PORTS = 100
    hosts_list = [ ('192.168.10.1', '00:00:00:00:00:01'), ('192.168.11.1', '00:00:00:00:02:01'), ]

    @classmethod
    def setUpClass(cls):
        cls.olt = OltConfig()
        cls.port_map, _ = cls.olt.olt_port_map()
        if not cls.port_map:
            cls.port_map = g_subscriber_port_map
        time.sleep(3)
        cls.load_device_id()

    @classmethod
    def tearDownClass(cls):
        '''Deactivate the vrouter apps'''
        #cls.vrouter_host_unload()

    @classmethod
    def load_device_id(cls):
        did = OnosCtrl.get_device_id()
        cls.device_id = did
        cls.device_dict = { "devices" : {
                "{}".format(did) : {
                    "basic" : {
                        "driver" : "softrouter"
                    }
                }
            },
        }

    def cliEnter(self):
        retries = 0
        while retries < 3:
            self.cli = OnosCliDriver(connect = True)
            if self.cli.handle:
                break
            else:
                retries += 1
                time.sleep(2)
    def cliExit(self):
        self.cli.disconnect()

    @classmethod
    def proxyarp_host_unload(cls):
        index = 1
        for host,_ in cls.hosts_list:
            iface = cls.port_map[index]
            index += 1
            config_cmds = ('ifconfig {} 0'.format(iface), )
            for cmd in config_cmds:
		log.info('host unload command %s' % cmd)
                os.system(cmd)

    @classmethod
    def interface_config_load(cls, interface_cfg = None):
  	if type(interface_cfg) is tuple:
            res = []
            for v in interface_cfg:
		if type(v) == list:
		    pass
		else:
                    res += v.items()
                    config = dict(res)
        else:
            config = interface_cfg
        cfg = json.dumps(config)
        with open('{}/network-cfg.json'.format(cls.onos_config_path), 'w') as f:
            f.write(cfg)
        return cord_test_onos_restart()

    @classmethod
    def host_config_load(cls, host_config = None):
	for host in host_config:
	    status, code = OnosCtrl.host_config(host)
	    if status is False:
                log.info('JSON request returned status %d' %code)
                assert_equal(status, True)

    @classmethod
    def generate_interface_config(cls, hosts = 1):
        num = 0
        start_host = ( 192 << 24) | ( 168 << 16)  |  (10 << 8) | 0
        end_host =   ( 200 << 24 ) | (168 << 16)  |  (10 << 8) | 0
        ports_dict = { 'ports' : {} }
        interface_list = []
        hosts_list = []
        for n in xrange(start_host, end_host, 256):
            port_map = ports_dict['ports']
            port = num + 1 if num < cls.MAX_PORTS - 1 else cls.MAX_PORTS - 1
            device_port_key = '{0}/{1}'.format(cls.device_id, port)
            try:
                interfaces = port_map[device_port_key]['interfaces']
            except:
                port_map[device_port_key] = { 'interfaces' : [] }
                interfaces = port_map[device_port_key]['interfaces']
            ip = n + 1
            host_ip = n + 2
            ips = '%d.%d.%d.%d/24'%( (ip >> 24) & 0xff, ( (ip >> 16) & 0xff ), ( (ip >> 8 ) & 0xff ), ip & 0xff)
            host = '%d.%d.%d.%d' % ( (host_ip >> 24) & 0xff, ( ( host_ip >> 16) & 0xff ), ( (host_ip >> 8 ) & 0xff ), host_ip & 0xff )
            mac = RandMAC()._fix()
            hosts_list.append((host, mac))
            if num < cls.MAX_PORTS - 1:
                interface_dict = { 'name' : 'b1-{}'.format(port), 'ips': [ips], 'mac' : mac }
                interfaces.append(interface_dict)
                interface_list.append(interface_dict['name'])
            else:
                interfaces[0]['ips'].append(ips)
            num += 1
            if num == hosts:
                break
        cls.hosts_list = hosts_list
        return (cls.device_dict, ports_dict, hosts_list)

    @classmethod
    def generate_host_config(cls):
        num = 0
        hosts_dict = {}
        for host, mac in cls.hosts_list:
            port = num + 1 if num < cls.MAX_PORTS - 1 else cls.MAX_PORTS - 1
	    hosts_dict[host] = {'mac':mac, 'vlan':'none', 'ipAddresses':[host], 'location':{ 'elementId' : '{}'.format(cls.device_id), 'port': port}}
            num += 1
        return hosts_dict.values()

    @classmethod
    def proxyarp_activate(cls, deactivate = False):
        app = 'org.onosproject.proxyarp'
        onos_ctrl = OnosCtrl(app)
        if deactivate is True:
            onos_ctrl.deactivate()
        else:
            onos_ctrl.activate()
        time.sleep(3)

    @classmethod
    def proxyarp_config(cls, hosts = 1):
        proxyarp_configs = cls.generate_interface_config(hosts = hosts)
	cls.interface_config_load(interface_cfg = proxyarp_configs)
	hostcfg = cls.generate_host_config()
	cls.host_config_load(host_config = hostcfg)
        return proxyarp_configs

    def proxyarp_arpreply_verify(self, ingress, hostip, hostmac, PositiveTest=True):
	log.info('verifying arp reply for host ip %s host mac %s on interface %s'%(hostip ,hostmac ,self.port_map[ingress]))
	self.success = False
        def recv_task():
            def recv_cb(pkt):
                log.info('Arp Reply seen with source Mac is %s' %(pkt[ARP].hwsrc))
                self.success = True if PositiveTest == True else False
            sniff(count=1, timeout=2, lfilter = lambda p: ARP in p and p[ARP].op == 2 and p[ARP].hwsrc == hostmac,
                  prn = recv_cb, iface = self.port_map[ingress])
        t = threading.Thread(target = recv_task)
        t.start()
        pkt = (Ether(dst = 'ff:ff:ff:ff:ff:ff')/ARP(op=1,pdst=hostip))
        log.info('sending arp request  for dest ip %s on interface %s' %
                 (hostip, self.port_map[ingress]))
        sendp( pkt, count = 10, iface = self.port_map[ingress])
        t.join()
	if PositiveTest:
            assert_equal(self.success, True)
	else:
	    assert_equal(self.success, False)

    def __proxyarp_hosts_verify(self, hosts = 1,PositiveTest = True):
        _,_,hosts_config = self.proxyarp_config(hosts = hosts)
	log.info('\nhosts_config %s and its type %s'%(hosts_config,type(hosts_config)))
        self.cliEnter()
        connected_hosts = json.loads(self.cli.hosts(jsonFormat = True))
        log.info('Discovered hosts: %s' %connected_hosts)
        #We read from cli if we expect less number of routes to avoid cli timeouts
        if hosts <= 10000:
            assert_equal(len(connected_hosts), hosts)
	ingress = hosts+1
	for hostip, hostmac in hosts_config:
	        self.proxyarp_arpreply_verify(ingress,hostip,hostmac,PositiveTest = PositiveTest)
		time.sleep(1)
	self.cliExit()
        return True

    def test_proxyarp_with_1_host(self, hosts=1):
        res = self.__proxyarp_hosts_verify(hosts = hosts)
        assert_equal(res, True)
	#cls.proxyarp_host_unload()
    def test_proxyarp_with_10_hosts(self, hosts=10):
        res = self.__proxyarp_hosts_verify(hosts = hosts)
        assert_equal(res, True)
    def test_proxyarp_with_50_hosts(self, hosts=50):
        res = self.__proxyarp_hosts_verify(hosts = hosts)
        assert_equal(res, True)
    def test_proxyarp_app_with_disabling_and_re_enabling(self,hosts = 3):
	ports_map, egress_map,hosts_config = self.proxyarp_config(hosts = hosts)
	ingress = hosts+1
	for hostip, hostmac in hosts_config:
	    self.proxyarp_arpreply_verify(ingress,hostip,hostmac,PositiveTest = True)
	    time.sleep(1)
	log.info('Deactivating proxyarp  app and expecting not to get arp reply from ONOS')
	self.proxyarp_activate(deactivate = True)
	for hostip, hostmac in hosts_config:
	    self.proxyarp_arpreply_verify(ingress,hostip,hostmac,PositiveTest = False)
	    time.sleep(1)
	log.info('activating proxyarp  app and expecting to get arp reply from ONOS')
	self.proxyarp_activate(deactivate = False)
	for hostip, hostmac in hosts_config:
            self.proxyarp_arpreply_verify(ingress,hostip,hostmac,PositiveTest = True)
            time.sleep(1)

    def test_proxyarp_nonexisting_host(self,hosts = 1):
    	_,_,hosts_config = self.proxyarp_config(hosts = hosts)
	ingress = hosts + 2
	for host, mac in hosts_config:
	    self.proxyarp_arpreply_verify(ingress,host,mac,PositiveTest = True)
	new_host = hosts_config[-1][0].split('.')
	new_host[2] = str(int(new_host[2])+1)
	new_host = '.'.join(new_host)
	new_mac =  RandMAC()._fix()
	log.info('verifying arp reply for host ip %s on interface %s'%(new_host,self.port_map[ingress]))
	res=srp1(Ether(dst='ff:ff:ff:ff:ff:ff')/ARP(op=1,pdst=new_host),timeout=2,iface=self.port_map[ingress])
	assert_equal(res, None)
	log.info('arp reply not seen for host ip %s on interface %s as expected'%(new_host,self.port_map[ingress]))
	hosts = hosts + 1
	_,_,hosts_config = self.proxyarp_config(hosts = hosts)
	for host in hosts_config:
	    if host[0] == new_host:
		new_mac = host[1]
	self.proxyarp_arpreply_verify(ingress,new_host,new_mac,PositiveTest = True)

    def test_proxyarp_removing_host(self,hosts = 3):
        ports_map, egress_map,hosts_config = self.proxyarp_config(hosts = hosts)
        ingress = hosts+1
        for hostip, hostmac in hosts_config:
            self.proxyarp_arpreply_verify(ingress,hostip,hostmac,PositiveTest = True)
            time.sleep(1)
	host_mac = hosts_config[0][1]
        log.info('removing host entry %s' % host_mac)
        self.cliEnter()
        hostentries = json.loads(self.cli.hosts(jsonFormat = True))
        for host in hostentries:
	    res = host_mac.upper() in host.values()
	    if res:
	 	break
	assert_equal(res, True)
        hostid = host_mac+'/'+'None'
        delete_host  = self.cli.host_remove(hostid)
        hostentries = json.loads(self.cli.hosts(jsonFormat = True))
	for host in hostentries:
            res = host_mac.upper() in host.values()
            if res:
                break
        assert_equal(res, False)
        self.proxyarp_arpreply_verify(ingress,hosts_config[0][0],host_mac,PositiveTest = False)
        time.sleep(1)
        self.cliExit()

    def test_proxyarp_concurrent_requests_with_multiple_host_and_different_interfaces(self,hosts = 10):
	ports_map, egress_map,hosts_config = self.proxyarp_config(hosts = hosts)
	self.success = True
	ingress = hosts+1
	ports = range(ingress,ingress+10)
	hostmac = []
	hostip = []
	for ip,mac in hosts_config:
	    hostmac.append(mac)
	    hostip.append(ip)
	success_dir = {}
	def verify_proxyarp(*r):
            ingress,hostmac,hostip = r[0],r[1],r[2]
            def mac_recv_task():
                def recv_cb(pkt):
		    log.info('Arp Reply seen with source Mac is %s' %(pkt[ARP].hwsrc))
                    success_dir[current_thread().name] = True
		sniff(count=1, timeout=5,lfilter = lambda p: ARP in p and p[ARP].op == 2 and p[ARP].hwsrc == hostmac,
                    prn = recv_cb, iface = self.port_map[ingress])
	    t = threading.Thread(target = mac_recv_task)
	    t.start()
	    pkt = (Ether(dst = 'ff:ff:ff:ff:ff:ff')/ARP(op=1,pdst= hostip))
            log.info('sending arp request  for dest ip %s on interface %s' %
                 (hostip,self.port_map[ingress]))
            sendp(pkt, count = 10,iface = self.port_map[ingress])
            t.join()
	t = []
	for i in range(10):
	    t.append(threading.Thread(target = verify_proxyarp, args = [ports[i],hostmac[i],hostip[i]]))
        for i in range(10):
	    t[i].start()
	for i in range(10):
            t[i].join()
        if len(success_dir) != 10:
                self.success = False
        assert_equal(self.success, True)

    def test_proxyarp_disabling_enabling_app_initiating_concurrent_requests(self,hosts = 10):
	'''Test sending arp requests to multiple host ips at once from different interfaces by disabling and re-enabling proxyarp app'''
        ports_map, egress_map,hosts_config = self.proxyarp_config(hosts = hosts)
        self.success = True
        ingress = hosts+1
        ports = range(ingress,ingress+10)
        hostmac = []
        hostip = []
        for ip,mac in hosts_config:
            hostmac.append(mac)
            hostip.append(ip)
        success_dir = {}
        def verify_proxyarp(*r):
            ingress,hostmac,hostip = r[0],r[1],r[2]
            def mac_recv_task():
                def recv_cb(pkt):
                    log.info('Arp Reply seen with source Mac is %s' %(pkt[ARP].hwsrc))
                    success_dir[current_thread().name] = True
                sniff(count=1, timeout=5,lfilter = lambda p: ARP in p and p[ARP].op == 2 and p[ARP].hwsrc == hostmac,
                    prn = recv_cb, iface = self.port_map[ingress])
            t = threading.Thread(target = mac_recv_task)
            t.start()
            pkt = (Ether(dst = 'ff:ff:ff:ff:ff:ff')/ARP(op=1,pdst= hostip))
            log.info('sending arp request  for dest ip %s on interface %s' %
                 (hostip,self.port_map[ingress]))
            sendp(pkt, count = 10,iface = self.port_map[ingress])
            t.join()
        t1 = []
	#starting multi threading before proxyarp disable
        for i in range(10):
            t1.append(threading.Thread(target = verify_proxyarp, args = [ports[i],hostmac[i],hostip[i]]))
        for i in range(10):
            t1[i].start()
        for i in range(10):
            t1[i].join()
        if len(success_dir) != 10:
                self.success = False
        assert_equal(self.success, True)
	self.proxyarp_activate(deactivate = True)
	#starting multi threading after proxyarp disable
	t2 = []
	self.success = False
	for i in range(10):
            t2.append(threading.Thread(target = verify_proxyarp, args = [ports[i],hostmac[i],hostip[i]]))
        for i in range(10):
            t2[i].start()
        for i in range(10):
            t2[i].join()
        if len(success_dir) != 10:
                self.success = True
        assert_equal(self.success, False)
	self.proxyarp_activate(deactivate = False)
	#starting multi threading after proxyarp re-enable
	self.success = True
	t3 = []
	for i in range(10):
            t3.append(threading.Thread(target = verify_proxyarp, args = [ports[i],hostmac[i],hostip[i]]))
        for i in range(10):
            t3[i].start()
        for i in range(10):
            t3[i].join()
        if len(success_dir) != 20:
                self.success = False
	assert_equal(self.success, True)

    def test_proxyarp_with_existing_and_non_existing_hostIPs_initiating_concurrent_requests(self,hosts = 5):
        ports_map, egress_map,hosts_config = self.proxyarp_config(hosts = hosts)
        self.success = True
        ingress = hosts+1
        ports = range(ingress,ingress+10)
        hostmac = []
        hostip = []
        for ip,mac in hosts_config:
            hostmac.append(mac)
            hostip.append(ip)
	#adding 5 non-existing host IPs to hostip list
	for i in range(1,6):
	    ip = hostip[-1].split('.')
	    ip[3] = str(int(ip[3])+int(i))
            ip = '.'.join(ip)
	    hostip.append(ip)
	    hostmac.append(RandMAC()._fix())
        success_dir = {}
	replied_hosts = []
        def verify_proxyarp(*r):
            ingress,hostmac,hostip = r[0],r[1],r[2]
            def mac_recv_task():
                def recv_cb(pkt):
                    log.info('Arp Reply seen with source Mac is %s' %(pkt[ARP].hwsrc))
                    success_dir[current_thread().name] = True
		    replied_hosts.append(hostip)
                sniff(count=1, timeout=5,lfilter = lambda p: ARP in p and p[ARP].op == 2 and p[ARP].psrc == hostip,
                    prn = recv_cb, iface = self.port_map[ingress])
            t = threading.Thread(target = mac_recv_task)
            t.start()
            pkt = (Ether(dst = 'ff:ff:ff:ff:ff:ff')/ARP(op=1,pdst= hostip))
            log.info('sending arp request  for dest ip %s on interface %s' %
                 (hostip,self.port_map[ingress]))
            sendp(pkt, count = 10,iface = self.port_map[ingress])
            t.join()
        t = []
        for i in range(10):
            t.append(threading.Thread(target = verify_proxyarp, args = [ports[i],hostmac[i],hostip[i]]))
        for i in range(10):
            t[i].start()
        for i in range(10):
            t[i].join()
        if len(success_dir) != 5 and len(replied_hosts) != 5:
                self.success = False
        assert_equal(self.success, True)
	for i in range(5):
	    if hostip[i] not in replied_hosts:
		self.success = False
	assert_equal(self.success, True)
