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

 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.packet_infos = {}
        pkts = []
        for pktid in self.packets:
            info = self.create_packet_info(src_if.sw_if_index, pktid)
            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.get_next_packet_info_for_interface2(
            self.pg0.sw_if_index, payload_info.dst, self.info)
        self.assertEqual(str(inner), str(self.info.data[IPver]))

    def checkCapture(self, gre4, isv4):
        out = self.pg0.get_capture()
        # This check is edited because RA appears in output, maybe disable RA?
        # self.assertEqual(len(out), 0)
        self.assertLess(len(out), 20)
        out = self.pg1.get_capture()
        self.assertEqual(len(out), len(self.packets))

        load = [0] * len(self.ass)
        self.info = None
        for p in out:
            try:
                asid = 0
                gre = None
                if 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]
                else:
                    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)
                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.log(
                    "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(gre4=True, 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")

    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(gre4=True, 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")

    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(gre4=False, isv4=True)
        finally:
            for asid in self.ass:
                self.vapi.cli("lb as 90.0.0.0/8 2002::%u" % (asid))
            self.vapi.cli("lb vip 90.0.0.0/8 encap gre6 del")

    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(gre4=False, 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")
