#!/usr/bin/env python3

import unittest
import random
import socket
from ipaddress import IPv4Address, IPv6Address, AddressValueError

from framework import VppTestCase, VppTestRunner
from util import ppp

from scapy.packet import Raw
from scapy.layers.l2 import Ether
from scapy.layers.inet import IP, UDP
from scapy.layers.inet6 import IPv6
from vpp_ip_route import VppIpRoute, VppRoutePath

try:
    text_type = unicode
except NameError:
    text_type = str

#
# The number of packets to sent.
#
N_PKTS_IN_STREAM = 300


class TestECMP(VppTestCase):
    """ Equal-cost multi-path routing Test Case """

    @classmethod
    def setUpClass(cls):
        """
        Perform standard class setup (defined by class method setUpClass in
        class VppTestCase) before running the test case, set test case related
        variables and configure VPP.
        """
        super(TestECMP, cls).setUpClass()

        # create 4 pg interfaces
        cls.create_pg_interfaces(range(4))

        # packet sizes to test
        cls.pg_if_packet_sizes = [64, 1500, 9018]

        # setup interfaces
        for i in cls.pg_interfaces:
            i.admin_up()
            i.generate_remote_hosts(5)
            i.config_ip4()
            i.resolve_arp()
            i.configure_ipv4_neighbors()
            i.config_ip6()
            i.resolve_ndp()
            i.configure_ipv6_neighbors()

    @classmethod
    def tearDownClass(cls):
        if not cls.vpp_dead:
            for i in cls.pg_interfaces:
                i.unconfig_ip4()
                i.unconfig_ip6()
                i.admin_down()

        super(TestECMP, cls).tearDownClass()

    def setUp(self):
        super(TestECMP, self).setUp()
        self.reset_packet_infos()

    def tearDown(self):
        """
        Show various debug prints after each test.
        """
        super(TestECMP, self).tearDown()

    def show_commands_at_teardown(self):
        self.logger.info(self.vapi.ppcli("show ip arp"))
        self.logger.info(self.vapi.ppcli("show ip6 neighbors"))

    def get_ip_address(self, ip_addr_start, ip_prefix_len):
        """

        :param str ip_addr_start: Starting IPv4 or IPv6 address.
        :param int ip_prefix_len: IP address prefix length.
        :return: Random IPv4 or IPv6 address from required range.
        """
        try:
            ip_addr = IPv4Address(text_type(ip_addr_start))
            ip_max_len = 32
        except (AttributeError, AddressValueError):
            ip_addr = IPv6Address(text_type(ip_addr_start))
            ip_max_len = 128

        return str(ip_addr +
                   random.randint(0, 2 ** (ip_max_len - ip_prefix_len) - 2))

    def create_stream(self, src_if, src_ip_start, dst_ip_start,
                      ip_prefix_len, packet_sizes, ip_l=IP):
        """Create input packet stream for defined interfaces.

        :param VppInterface src_if: Source Interface for packet stream.
        :param str src_ip_start: Starting source IPv4 or IPv6 address.
        :param str dst_ip_start: Starting destination IPv4 or IPv6 address.
        :param int ip_prefix_len: IP address prefix length.
        :param list packet_sizes: packet size to test.
        :param Scapy ip_l: Required IP layer - IP or IPv6. (Default is IP.)
        """
        pkts = []
        for i in range(0, N_PKTS_IN_STREAM):
            info = self.create_packet_info(src_if, src_if)
            payload = self.info_to_payload(info)
            src_ip = self.get_ip_address(src_ip_start, ip_prefix_len)
            dst_ip = self.get_ip_address(dst_ip_start, ip_prefix_len)
            p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
                 ip_l(src=src_ip, dst=dst_ip) /
                 UDP(sport=1234, dport=1234) /
                 Raw(payload))
            info.data = p.copy()
            size = random.choice(packet_sizes)
            self.extend_packet(p, size)
            pkts.append(p)
        return pkts

    def verify_capture(self, rx_if, capture, ip_l=IP):
        """Verify captured input packet stream for defined interface.

        :param VppInterface rx_if: Interface to verify captured packet stream.
        :param list capture: Captured packet stream.
        :param Scapy ip_l: Required IP layer - IP or IPv6. (Default is IP.)
        """
        self.logger.info("Verifying capture on interface %s" % rx_if.name)

        count = 0
        host_counters = {}
        for host_mac in rx_if._hosts_by_mac:
            host_counters[host_mac] = 0

        for packet in capture:
            try:
                ip_received = packet[ip_l]
                payload_info = self.payload_to_info(packet[Raw])
                packet_index = payload_info.index
                ip_sent = self._packet_infos[packet_index].data[ip_l]
                self.logger.debug("Got packet on port %s: src=%u (id=%u)" %
                                  (rx_if.name, payload_info.src, packet_index))
                # Check standard fields
                self.assertIn(packet.dst, rx_if._hosts_by_mac,
                              "Destination MAC address %s shouldn't be routed "
                              "via interface %s" % (packet.dst, rx_if.name))
                self.assertEqual(packet.src, rx_if.local_mac)
                self.assertEqual(ip_received.src, ip_sent.src)
                self.assertEqual(ip_received.dst, ip_sent.dst)
                host_counters[packet.dst] += 1
                self._packet_infos.pop(packet_index)

            except:
                self.logger.error(ppp("Unexpected or invalid packet:", packet))
                raise

        # We expect packet routed via all host of pg interface
        for host_mac in host_counters:
            nr = host_counters[host_mac]
            self.assertNotEqual(
                nr, 0, "No packet routed via host %s" % host_mac)
            self.logger.info("%u packets routed via host %s of %s interface" %
                             (nr, host_mac, rx_if.name))
            count += nr
        self.logger.info("Total amount of %u packets routed via %s interface" %
                         (count, rx_if.name))

        return count

    def create_ip_routes(self, dst_ip_net, dst_prefix_len, is_ipv6=0):
        """
        Create IP routes for defined destination IP network.

        :param str dst_ip_net: Destination IP network.
        :param int dst_prefix_len: IP address prefix length.
        :param int is_ipv6: 0 if an ip4 route, else ip6
        """

        paths = []
        for pg_if in self.pg_interfaces[1:]:
            for nh_host in pg_if.remote_hosts:
                nh_host_ip = nh_host.ip4 if is_ipv6 == 0 else nh_host.ip6
                paths.append(VppRoutePath(nh_host_ip,
                                          pg_if.sw_if_index))

        rip = VppIpRoute(self, dst_ip_net, dst_prefix_len, paths)
        rip.add_vpp_config()
        self.logger.info("Route via %s on %s created" %
                         (nh_host_ip, pg_if.name))

        self.logger.debug(self.vapi.ppcli("show ip fib"))
        self.logger.debug(self.vapi.ppcli("show ip6 fib"))

    def test_ip_ecmp(self):
        """ IP equal-cost multi-path routing test """

        src_ip_net = '16.0.0.1'
        dst_ip_net = '32.0.0.1'
        ip_prefix_len = 24

        self.create_ip_routes(dst_ip_net, ip_prefix_len)

        pkts = self.create_stream(self.pg0, src_ip_net, dst_ip_net,
                                  ip_prefix_len, self.pg_if_packet_sizes)
        self.pg0.add_stream(pkts)

        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        # We expect packets on pg1, pg2 and pg3, but not on pg0
        rx_count = 0
        for pg_if in self.pg_interfaces[1:]:
            capture = pg_if._get_capture(timeout=1)
            self.assertNotEqual(
                len(capture), 0, msg="No packets captured on %s" % pg_if.name)
            rx_count += self.verify_capture(pg_if, capture)
        self.pg0.assert_nothing_captured(remark="IP packets forwarded on pg0")

        # Check that all packets were forwarded via pg1, pg2 and pg3
        self.assertEqual(rx_count, len(pkts))

    def test_ip6_ecmp(self):
        """ IPv6 equal-cost multi-path routing test """

        src_ip_net = '3ffe:51::1'
        dst_ip_net = '3ffe:71::1'
        ip_prefix_len = 64

        self.create_ip_routes(dst_ip_net, ip_prefix_len, is_ipv6=1)

        pkts = self.create_stream(
            self.pg0, src_ip_net, dst_ip_net,
            ip_prefix_len, self.pg_if_packet_sizes, ip_l=IPv6)
        self.pg0.add_stream(pkts)

        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        # We expect packets on pg1, pg2 and pg3, but not on pg0
        rx_count = 0
        for pg_if in self.pg_interfaces[1:]:
            capture = pg_if._get_capture(timeout=1)
            self.assertNotEqual(
                len(capture), 0, msg="No packets captured on %s" % pg_if.name)
            rx_count += self.verify_capture(pg_if, capture, ip_l=IPv6)
        self.pg0.assert_nothing_captured(remark="IP packets forwarded on pg0")

        # Check that all packets were forwarded via pg1, pg2 and pg3
        self.assertEqual(rx_count, len(pkts))


if __name__ == '__main__':
    unittest.main(testRunner=VppTestRunner)
