import socket

from scapy.layers.inet import IP, UDP
from scapy.layers.inet6 import IPv6
from scapy.layers.l2 import Ether, GRE
from scapy.packet import Raw

from framework import VppTestCase
from util import ppp

""" TestLB is a subclass of  VPPTestCase classes.

 TestLB class defines Load Balancer test cases for:
  - IP4 to GRE4 encap
  - IP4 to GRE6 encap
  - IP6 to GRE4 encap
  - IP6 to GRE6 encap
  - IP4 to L3DSR encap
  - IP4 to NAT4 encap
  - IP6 to NAT6 encap

 As stated in comments below, GRE has issues with IPv6.
 All test cases involving IPv6 are executed, but
 received packets are not parsed and checked.

"""


class TestLB(VppTestCase):
    """ Load Balancer Test Case """

    @classmethod
    def setUpClass(cls):
        super(TestLB, cls).setUpClass()

        cls.ass = range(5)
        cls.packets = range(100)

        try:
            cls.create_pg_interfaces(range(2))
            cls.interfaces = list(cls.pg_interfaces)

            for i in cls.interfaces:
                i.admin_up()
                i.config_ip4()
                i.config_ip6()
                i.disable_ipv6_ra()
                i.resolve_arp()
                i.resolve_ndp()
            dst4 = socket.inet_pton(socket.AF_INET, "10.0.0.0")
            dst6 = socket.inet_pton(socket.AF_INET6, "2002::")
            cls.vapi.ip_add_del_route(dst4, 24, cls.pg1.remote_ip4n)
            cls.vapi.ip_add_del_route(dst6, 16, cls.pg1.remote_ip6n, is_ipv6=1)
            cls.vapi.cli("lb conf ip4-src-address 39.40.41.42")
            cls.vapi.cli("lb conf ip6-src-address 2004::1")
        except Exception:
            super(TestLB, cls).tearDownClass()
            raise

    def tearDown(self):
        super(TestLB, self).tearDown()
        if not self.vpp_dead:
            self.logger.info(self.vapi.cli("show lb vip verbose"))

    def getIPv4Flow(self, id):
        return (IP(dst="90.0.%u.%u" % (id / 255, id % 255),
                   src="40.0.%u.%u" % (id / 255, id % 255)) /
                UDP(sport=10000 + id, dport=20000 + id))

    def getIPv6Flow(self, id):
        return (IPv6(dst="2001::%u" % (id), src="fd00:f00d:ffff::%u" % (id)) /
                UDP(sport=10000 + id, dport=20000 + id))

    def generatePackets(self, src_if, isv4):
        self.reset_packet_infos()
        pkts = []
        for pktid in self.packets:
            info = self.create_packet_info(src_if, self.pg1)
            payload = self.info_to_payload(info)
            ip = self.getIPv4Flow(pktid) if isv4 else self.getIPv6Flow(pktid)
            packet = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
                      ip /
                      Raw(payload))
            self.extend_packet(packet, 128)
            info.data = packet.copy()
            pkts.append(packet)
        return pkts

    def checkInner(self, gre, isv4):
        IPver = IP if isv4 else IPv6
        self.assertEqual(gre.proto, 0x0800 if isv4 else 0x86DD)
        self.assertEqual(gre.flags, 0)
        self.assertEqual(gre.version, 0)
        inner = IPver(str(gre.payload))
        payload_info = self.payload_to_info(str(inner[Raw]))
        self.info = self.packet_infos[payload_info.index]
        self.assertEqual(payload_info.src, self.pg0.sw_if_index)
        self.assertEqual(str(inner), str(self.info.data[IPver]))

    def checkCapture(self, encap, isv4):
        self.pg0.assert_nothing_captured()
        out = self.pg1.get_capture(len(self.packets))

        load = [0] * len(self.ass)
        self.info = None
        for p in out:
            try:
                asid = 0
                gre = None
                if (encap == 'gre4'):
                    ip = p[IP]
                    asid = int(ip.dst.split(".")[3])
                    self.assertEqual(ip.version, 4)
                    self.assertEqual(ip.flags, 0)
                    self.assertEqual(ip.src, "39.40.41.42")
                    self.assertEqual(ip.dst, "10.0.0.%u" % asid)
                    self.assertEqual(ip.proto, 47)
                    self.assertEqual(len(ip.options), 0)
                    self.assertGreaterEqual(ip.ttl, 64)
                    gre = p[GRE]
                    self.checkInner(gre, isv4)
                elif (encap == 'gre6'):
                    ip = p[IPv6]
                    asid = ip.dst.split(":")
                    asid = asid[len(asid) - 1]
                    asid = 0 if asid == "" else int(asid)
                    self.assertEqual(ip.version, 6)
                    self.assertEqual(ip.tc, 0)
                    self.assertEqual(ip.fl, 0)
                    self.assertEqual(ip.src, "2004::1")
                    self.assertEqual(
                        socket.inet_pton(socket.AF_INET6, ip.dst),
                        socket.inet_pton(socket.AF_INET6, "2002::%u" % asid)
                    )
                    self.assertEqual(ip.nh, 47)
                    self.assertGreaterEqual(ip.hlim, 64)
                    # self.assertEqual(len(ip.options), 0)
                    gre = GRE(str(p[IPv6].payload))
                    self.checkInner(gre, isv4)
                elif (encap == 'l3dsr'):
                    ip = p[IP]
                    asid = int(ip.dst.split(".")[3])
                    self.assertEqual(ip.version, 4)
                    self.assertEqual(ip.flags, 0)
                    self.assertEqual(ip.dst, "10.0.0.%u" % asid)
                    self.assertEqual(ip.tos, 0x1c)
                    self.assertEqual(len(ip.options), 0)
                elif (encap == 'nat4'):
                    ip = p[IP]
                    asid = int(ip.dst.split(".")[3])
                    self.assertEqual(ip.version, 4)
                    self.assertEqual(ip.flags, 0)
                    self.assertEqual(ip.dst, "10.0.0.%u" % asid)
                    self.assertEqual(ip.proto, 17)
                    self.assertEqual(len(ip.options), 0)
                    self.assertGreaterEqual(ip.ttl, 63)
                    udp = p[UDP]
                    self.assertEqual(udp.dport, 3307)
                elif (encap == 'nat6'):
                    ip = p[IPv6]
                    asid = ip.dst.split(":")
                    asid = asid[len(asid) - 1]
                    asid = 0 if asid == "" else int(asid)
                    self.assertEqual(ip.version, 6)
                    self.assertEqual(ip.tc, 0)
                    self.assertEqual(ip.fl, 0)
                    self.assertEqual(
                        socket.inet_pton(socket.AF_INET6, ip.dst),
                        socket.inet_pton(socket.AF_INET6, "2002::%u" % asid)
                    )
                    self.assertEqual(ip.nh, 17)
                    self.assertGreaterEqual(ip.hlim, 63)
                    udp = UDP(str(p[IPv6].payload))
                    self.assertEqual(udp.dport, 3307)
                load[asid] += 1
            except:
                self.logger.error(ppp("Unexpected or invalid packet:", p))
                raise

        # This is just to roughly check that the balancing algorithm
        # is not completly biased.
        for asid in self.ass:
            if load[asid] < len(self.packets) / (len(self.ass) * 2):
                self.logger.error(
                    "ASS is not balanced: load[%d] = %d" % (asid, load[asid]))
                raise Exception("Load Balancer algorithm is biased")

    def test_lb_ip4_gre4(self):
        """ Load Balancer IP4 GRE4 """
        try:
            self.vapi.cli("lb vip 90.0.0.0/8 encap gre4")
            for asid in self.ass:
                self.vapi.cli("lb as 90.0.0.0/8 10.0.0.%u" % (asid))

            self.pg0.add_stream(self.generatePackets(self.pg0, isv4=True))
            self.pg_enable_capture(self.pg_interfaces)
            self.pg_start()
            self.checkCapture(encap='gre4', isv4=True)

        finally:
            for asid in self.ass:
                self.vapi.cli("lb as 90.0.0.0/8 10.0.0.%u del" % (asid))
            self.vapi.cli("lb vip 90.0.0.0/8 encap gre4 del")
            self.vapi.cli("test lb flowtable flush")

    def test_lb_ip6_gre4(self):
        """ Load Balancer IP6 GRE4 """

        try:
            self.vapi.cli("lb vip 2001::/16 encap gre4")
            for asid in self.ass:
                self.vapi.cli("lb as 2001::/16 10.0.0.%u" % (asid))

            self.pg0.add_stream(self.generatePackets(self.pg0, isv4=False))
            self.pg_enable_capture(self.pg_interfaces)
            self.pg_start()

            self.checkCapture(encap='gre4', isv4=False)
        finally:
            for asid in self.ass:
                self.vapi.cli("lb as 2001::/16 10.0.0.%u del" % (asid))
            self.vapi.cli("lb vip 2001::/16 encap gre4 del")
            self.vapi.cli("test lb flowtable flush")

    def test_lb_ip4_gre6(self):
        """ Load Balancer IP4 GRE6 """
        try:
            self.vapi.cli("lb vip 90.0.0.0/8 encap gre6")
            for asid in self.ass:
                self.vapi.cli("lb as 90.0.0.0/8 2002::%u" % (asid))

            self.pg0.add_stream(self.generatePackets(self.pg0, isv4=True))
            self.pg_enable_capture(self.pg_interfaces)
            self.pg_start()

            self.checkCapture(encap='gre6', isv4=True)
        finally:
            for asid in self.ass:
                self.vapi.cli("lb as 90.0.0.0/8 2002::%u del" % (asid))
            self.vapi.cli("lb vip 90.0.0.0/8 encap gre6 del")
            self.vapi.cli("test lb flowtable flush")

    def test_lb_ip6_gre6(self):
        """ Load Balancer IP6 GRE6 """
        try:
            self.vapi.cli("lb vip 2001::/16 encap gre6")
            for asid in self.ass:
                self.vapi.cli("lb as 2001::/16 2002::%u" % (asid))

            self.pg0.add_stream(self.generatePackets(self.pg0, isv4=False))
            self.pg_enable_capture(self.pg_interfaces)
            self.pg_start()

            self.checkCapture(encap='gre6', isv4=False)
        finally:
            for asid in self.ass:
                self.vapi.cli("lb as 2001::/16 2002::%u del" % (asid))
            self.vapi.cli("lb vip 2001::/16 encap gre6 del")
            self.vapi.cli("test lb flowtable flush")

    def test_lb_ip4_l3dsr(self):
        """ Load Balancer IP4 L3DSR """
        try:
            self.vapi.cli("lb vip 90.0.0.0/8 encap l3dsr dscp 7")
            for asid in self.ass:
                self.vapi.cli("lb as 90.0.0.0/8 10.0.0.%u" % (asid))

            self.pg0.add_stream(self.generatePackets(self.pg0, isv4=True))
            self.pg_enable_capture(self.pg_interfaces)
            self.pg_start()
            self.checkCapture(encap='l3dsr', isv4=True)

        finally:
            for asid in self.ass:
                self.vapi.cli("lb as 90.0.0.0/8 10.0.0.%u del" % (asid))
            self.vapi.cli("lb vip 90.0.0.0/8 encap l3dsr dscp 7 del")
            self.vapi.cli("test lb flowtable flush")

    def test_lb_ip4_nat4(self):
        """ Load Balancer IP4 NAT4 """
        try:
            self.vapi.cli("lb vip 90.0.0.0/8 encap nat4"
                          " type clusterip port 3306 target_port 3307")
            for asid in self.ass:
                self.vapi.cli("lb as 90.0.0.0/8 10.0.0.%u" % (asid))

            self.pg0.add_stream(self.generatePackets(self.pg0, isv4=True))
            self.pg_enable_capture(self.pg_interfaces)
            self.pg_start()
            self.checkCapture(encap='nat4', isv4=True)

        finally:
            for asid in self.ass:
                self.vapi.cli("lb as 90.0.0.0/8 10.0.0.%u del" % (asid))
            self.vapi.cli("lb vip 90.0.0.0/8 encap nat4"
                          " type clusterip port 3306 target_port 3307 del")
            self.vapi.cli("test lb flowtable flush")

    def test_lb_ip6_nat6(self):
        """ Load Balancer IP6 NAT6 """
        try:
            self.vapi.cli("lb vip 2001::/16 encap nat6"
                          " type clusterip port 3306 target_port 3307")
            for asid in self.ass:
                self.vapi.cli("lb as 2001::/16 2002::%u" % (asid))

            self.pg0.add_stream(self.generatePackets(self.pg0, isv4=False))
            self.pg_enable_capture(self.pg_interfaces)
            self.pg_start()
            self.checkCapture(encap='nat6', isv4=False)

        finally:
            for asid in self.ass:
                self.vapi.cli("lb as 2001::/16 2002::%u del" % (asid))
            self.vapi.cli("lb vip 2001::/16 encap nat6"
                          " type clusterip port 3306 target_port 3307 del")
            self.vapi.cli("test lb flowtable flush")
