#!/usr/bin/env python

import unittest

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

from framework import VppTestCase, VppTestRunner
from util import Host, ppp


class TestSpan(VppTestCase):
    """ SPAN Test Case """

    # Test variables
    hosts_nr = 10           # Number of hosts
    pkts_per_burst = 257    # Number of packets per burst

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

    def setUp(self):
        super(TestSpan, self).setUp()

        # create 3 pg interfaces
        self.create_pg_interfaces(range(3))

        # packet flows mapping pg0 -> pg1, pg2 -> pg3, etc.
        self.flows = dict()
        self.flows[self.pg0] = [self.pg1]

        # packet sizes
        self.pg_if_packet_sizes = [64, 512]  # , 1518, 9018]

        self.interfaces = list(self.pg_interfaces)

        # Create host MAC and IPv4 lists
        # self.MY_MACS = dict()
        # self.MY_IP4S = dict()
        self.create_host_lists(TestSpan.hosts_nr)

        # Create bi-directional cross-connects between pg0 and pg1
        self.vapi.sw_interface_set_l2_xconnect(
            self.pg0.sw_if_index, self.pg1.sw_if_index, enable=1)
        self.vapi.sw_interface_set_l2_xconnect(
            self.pg1.sw_if_index, self.pg0.sw_if_index, enable=1)

        # setup all interfaces
        for i in self.interfaces:
            i.admin_up()
            i.config_ip4()
            i.resolve_arp()

        # Enable SPAN on pg0 (mirrored to pg2)
        self.vapi.sw_interface_span_enable_disable(
            self.pg0.sw_if_index, self.pg2.sw_if_index)

    def tearDown(self):
        super(TestSpan, self).tearDown()

    def create_host_lists(self, count):
        """ Method to create required number of MAC and IPv4 addresses.
        Create required number of host MAC addresses and distribute them among
        interfaces. Create host IPv4 address for every host MAC address too.

        :param count: Number of hosts to create MAC and IPv4 addresses for.
        """
        # mapping between packet-generator index and lists of test hosts
        self.hosts_by_pg_idx = dict()

        for pg_if in self.pg_interfaces:
            # self.MY_MACS[i.sw_if_index] = []
            # self.MY_IP4S[i.sw_if_index] = []
            self.hosts_by_pg_idx[pg_if.sw_if_index] = []
            hosts = self.hosts_by_pg_idx[pg_if.sw_if_index]
            for j in range(0, count):
                host = Host(
                    "00:00:00:ff:%02x:%02x" % (pg_if.sw_if_index, j),
                    "172.17.1%02x.%u" % (pg_if.sw_if_index, j))
                hosts.append(host)

    def create_stream(self, src_if, packet_sizes):
        pkts = []
        for i in range(0, TestSpan.pkts_per_burst):
            dst_if = self.flows[src_if][0]
            pkt_info = self.create_packet_info(
                src_if.sw_if_index, dst_if.sw_if_index)
            payload = self.info_to_payload(pkt_info)
            p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
                 IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4) /
                 UDP(sport=1234, dport=1234) /
                 Raw(payload))
            pkt_info.data = p.copy()
            size = packet_sizes[(i / 2) % len(packet_sizes)]
            self.extend_packet(p, size)
            pkts.append(p)
        return pkts

    def verify_capture(self, dst_if, capture_pg1, capture_pg2):
        last_info = dict()
        for i in self.interfaces:
            last_info[i.sw_if_index] = None
        dst_sw_if_index = dst_if.sw_if_index
        if len(capture_pg1) != len(capture_pg2):
            self.logger.error(
                "Different number of outgoing and mirrored packets : %u != %u" %
                (len(capture_pg1), len(capture_pg2)))
            raise
        for pkt_pg1, pkt_pg2 in zip(capture_pg1, capture_pg2):
            try:
                ip1 = pkt_pg1[IP]
                udp1 = pkt_pg1[UDP]
                raw1 = pkt_pg1[Raw]

                if pkt_pg1[Ether] != pkt_pg2[Ether]:
                    self.logger.error("Different ethernet header of "
                                      "outgoing and mirrored packet")
                    raise
                if ip1 != pkt_pg2[IP]:
                    self.logger.error(
                        "Different ip header of outgoing and mirrored packet")
                    raise
                if udp1 != pkt_pg2[UDP]:
                    self.logger.error(
                        "Different udp header of outgoing and mirrored packet")
                    raise
                if raw1 != pkt_pg2[Raw]:
                    self.logger.error(
                        "Different raw data of outgoing and mirrored packet")
                    raise

                payload_info = self.payload_to_info(str(raw1))
                packet_index = payload_info.index
                self.assertEqual(payload_info.dst, dst_sw_if_index)
                self.logger.debug(
                    "Got packet on port %s: src=%u (id=%u)" %
                    (dst_if.name, payload_info.src, packet_index))
                next_info = self.get_next_packet_info_for_interface2(
                    payload_info.src, dst_sw_if_index,
                    last_info[payload_info.src])
                last_info[payload_info.src] = next_info
                self.assertTrue(next_info is not None)
                self.assertEqual(packet_index, next_info.index)
                saved_packet = next_info.data
                # Check standard fields
                self.assertEqual(ip1.src, saved_packet[IP].src)
                self.assertEqual(ip1.dst, saved_packet[IP].dst)
                self.assertEqual(udp1.sport, saved_packet[UDP].sport)
                self.assertEqual(udp1.dport, saved_packet[UDP].dport)
            except:
                self.logger.error("Unexpected or invalid packets:")
                self.logger.error(ppp("pg1 packet:", pkt_pg1))
                self.logger.error(ppp("pg2 packet:", pkt_pg2))
                raise
        for i in self.interfaces:
            remaining_packet = self.get_next_packet_info_for_interface2(
                i, dst_sw_if_index, last_info[i.sw_if_index])
            self.assertTrue(remaining_packet is None,
                            "Port %u: Packet expected from source %u didn't"
                            " arrive" % (dst_sw_if_index, i.sw_if_index))

    def test_span(self):
        """ SPAN test

        Test scenario:
            1. config
               3 interfaces, pg0 l2xconnected with pg1
            2. sending l2 eth packets between 2 interfaces (pg0, pg1) and
               mirrored to pg2
               64B, 512B, 1518B, 9018B (ether_size)
               burst of packets per interface
        """

        # Create incoming packet streams for packet-generator interfaces
        pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes)
        self.pg0.add_stream(pkts)

        # Enable packet capturing and start packet sending
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        # Verify packets outgoing packet streams on mirrored interface (pg2)
        self.logger.info("Verifying capture on interfaces %s and %s" %
                         (self.pg1.name, self.pg2.name))
        self.verify_capture(self.pg1,
                            self.pg1.get_capture(),
                            self.pg2.get_capture())


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