#!/usr/bin/env python

import binascii
import socket
from socket import AF_INET, AF_INET6
import unittest
import sys

from framework import VppTestCase

from scapy.packet import Raw
from scapy.layers.l2 import Ether
from scapy.layers.inet import IP, UDP, TCP
from scapy.layers.inet6 import IPv6
from util import ppp


class TestClassifier(VppTestCase):

    @staticmethod
    def _resolve_mask_match(mask_match):
        mask_match = binascii.unhexlify(mask_match)
        mask_match_len = ((len(mask_match) - 1) // 16 + 1) * 16
        mask_match = mask_match + b'\0' * \
            (mask_match_len - len(mask_match))
        return mask_match, mask_match_len

    @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(TestClassifier, cls).setUpClass()
        cls.acl_active_table = ''
        cls.af = AF_INET

    def setUp(self):
        """
        Perform test setup before test case.

        **Config:**
            - create 4 pg interfaces
                - untagged pg0/pg1/pg2 interface
                    pg0 -------> pg1 (IP ACL)
                           \
                            ---> pg2 (MAC ACL))
                             \
                              -> pg3 (PBR)
            - setup interfaces:
                - put it into UP state
                - set IPv4/6 addresses
                - resolve neighbor address using ARP

        :ivar list interfaces: pg interfaces.
        :ivar list pg_if_packet_sizes: packet sizes in test.
        :ivar dict acl_tbl_idx: ACL table index.
        :ivar int pbr_vrfid: VRF id for PBR test.
        """
        self.reset_packet_infos()
        super(TestClassifier, self).setUp()
        if self.af is None:  # l2_acl test case
            return

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

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

        self.interfaces = list(self.pg_interfaces)

        # ACL & PBR vars
        self.acl_tbl_idx = {}
        self.pbr_vrfid = 200

        # setup all interfaces
        for intf in self.interfaces:
            intf.admin_up()
            if self.af == AF_INET:
                intf.config_ip4()
                intf.resolve_arp()
            elif self.af == AF_INET6:
                intf.config_ip6()
                intf.resolve_ndp()

    def tearDown(self):
        """Run standard test teardown and acl related log."""
        if self.af is not None and not self.vpp_dead:
            if self.af == AF_INET:
                self.logger.info(self.vapi.ppcli("show inacl type ip4"))
                self.logger.info(self.vapi.ppcli("show outacl type ip4"))
            elif self.af == AF_INET6:
                self.logger.info(self.vapi.ppcli("show inacl type ip6"))
                self.logger.info(self.vapi.ppcli("show outacl type ip6"))

            self.logger.info(self.vapi.cli("show classify table verbose"))
            self.logger.info(self.vapi.cli("show ip fib"))

            acl_active_table = 'ip_out'
            if self.af == AF_INET6:
                acl_active_table = 'ip6_out'

            if self.acl_active_table == acl_active_table:
                self.output_acl_set_interface(
                    self.pg0, self.acl_tbl_idx.get(self.acl_active_table), 0)
                self.acl_active_table = ''
            elif self.acl_active_table != '':
                self.input_acl_set_interface(
                    self.pg0, self.acl_tbl_idx.get(self.acl_active_table), 0)
                self.acl_active_table = ''

            for intf in self.interfaces:
                if self.af == AF_INET:
                    intf.unconfig_ip4()
                elif self.af == AF_INET6:
                    intf.unconfig_ip6()
                intf.admin_down()

        super(TestClassifier, self).tearDown()

    @staticmethod
    def build_mac_match(dst_mac='', src_mac='', ether_type=''):
        """Build MAC ACL match data with hexstring format.

        :param str dst_mac: source MAC address <x:x:x:x:x:x>
        :param str src_mac: destination MAC address <x:x:x:x:x:x>
        :param str ether_type: ethernet type <0-ffff>
        """
        if dst_mac:
            dst_mac = dst_mac.replace(':', '')
        if src_mac:
            src_mac = src_mac.replace(':', '')

        return ('{!s:0>12}{!s:0>12}{!s:0>4}'.format(
            dst_mac, src_mac, ether_type)).rstrip('0')

    @staticmethod
    def build_mac_mask(dst_mac='', src_mac='', ether_type=''):
        """Build MAC ACL mask data with hexstring format.

        :param str dst_mac: source MAC address <0-ffffffffffff>
        :param str src_mac: destination MAC address <0-ffffffffffff>
        :param str ether_type: ethernet type <0-ffff>
        """

        return ('{!s:0>12}{!s:0>12}{!s:0>4}'.format(
            dst_mac, src_mac, ether_type)).rstrip('0')

    @staticmethod
    def build_ip_mask(proto='', src_ip='', dst_ip='',
                      src_port='', dst_port=''):
        """Build IP ACL mask data with hexstring format.

        :param str proto: protocol number <0-ff>
        :param str src_ip: source ip address <0-ffffffff>
        :param str dst_ip: destination ip address <0-ffffffff>
        :param str src_port: source port number <0-ffff>
        :param str dst_port: destination port number <0-ffff>
        """

        return ('{!s:0>20}{!s:0>12}{!s:0>8}{!s:0>4}{!s:0>4}'.format(
            proto, src_ip, dst_ip, src_port, dst_port)).rstrip('0')

    @staticmethod
    def build_ip6_mask(nh='', src_ip='', dst_ip='',
                       src_port='', dst_port=''):
        """Build IPv6 ACL mask data with hexstring format.

        :param str nh: next header number <0-ff>
        :param str src_ip: source ip address <0-ffffffff>
        :param str dst_ip: destination ip address <0-ffffffff>
        :param str src_port: source port number <0-ffff>
        :param str dst_port: destination port number <0-ffff>
        """

        return ('{!s:0>14}{!s:0>34}{!s:0>32}{!s:0>4}{!s:0>4}'.format(
            nh, src_ip, dst_ip, src_port, dst_port)).rstrip('0')

    @staticmethod
    def build_ip_match(proto=0, src_ip='', dst_ip='',
                       src_port=0, dst_port=0):
        """Build IP ACL match data with hexstring format.

        :param int proto: protocol number with valid option "x"
        :param str src_ip: source ip address with format of "x.x.x.x"
        :param str dst_ip: destination ip address with format of "x.x.x.x"
        :param int src_port: source port number "x"
        :param int dst_port: destination port number "x"
        """
        if src_ip:
            src_ip = binascii.hexlify(socket.inet_aton(src_ip)).decode('ascii')
        if dst_ip:
            dst_ip = binascii.hexlify(socket.inet_aton(dst_ip)).decode('ascii')

        return ('{!s:0>20}{!s:0>12}{!s:0>8}{!s:0>4}{!s:0>4}'.format(
            hex(proto)[2:], src_ip, dst_ip, hex(src_port)[2:],
            hex(dst_port)[2:])).rstrip('0')

    @staticmethod
    def build_ip6_match(nh=0, src_ip='', dst_ip='',
                        src_port=0, dst_port=0):
        """Build IPv6 ACL match data with hexstring format.

        :param int nh: next header number with valid option "x"
        :param str src_ip: source ip6 address with format of "xxx:xxxx::xxxx"
        :param str dst_ip: destination ip6 address with format of
            "xxx:xxxx::xxxx"
        :param int src_port: source port number "x"
        :param int dst_port: destination port number "x"
        """
        if src_ip:
            if sys.version_info[0] == 2:
                src_ip = binascii.hexlify(socket.inet_pton(
                    socket.AF_INET6, src_ip))
            else:
                src_ip = socket.inet_pton(socket.AF_INET6, src_ip).hex()

        if dst_ip:
            if sys.version_info[0] == 2:
                dst_ip = binascii.hexlify(socket.inet_pton(
                    socket.AF_INET6, dst_ip))
            else:
                dst_ip = socket.inet_pton(socket.AF_INET6, dst_ip).hex()

        return ('{!s:0>14}{!s:0>34}{!s:0>32}{!s:0>4}{!s:0>4}'.format(
            hex(nh)[2:], src_ip, dst_ip, hex(src_port)[2:],
            hex(dst_port)[2:])).rstrip('0')

    def create_stream(self, src_if, dst_if, packet_sizes,
                      proto_l=UDP(sport=1234, dport=5678)):
        """Create input packet stream for defined interfaces.

        :param VppInterface src_if: Source Interface for packet stream.
        :param VppInterface dst_if: Destination Interface for packet stream.
        :param list packet_sizes: packet size to test.
        :param Scapy proto_l: Required IP protocol. Default protocol is UDP.
        """
        pkts = []

        for size in packet_sizes:
            info = self.create_packet_info(src_if, dst_if)
            payload = self.info_to_payload(info)
            if self.af == AF_INET:
                p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
                     IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4) /
                     proto_l /
                     Raw(payload))
            elif self.af == AF_INET6:
                p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
                     IPv6(src=src_if.remote_ip6, dst=dst_if.remote_ip6) /
                     proto_l /
                     Raw(payload))
            info.data = p.copy()
            self.extend_packet(p, size)
            pkts.append(p)
        return pkts

    def verify_capture(self, dst_if, capture, proto_l=UDP):
        """Verify captured input packet stream for defined interface.

        :param VppInterface dst_if: Interface to verify captured packet stream.
        :param list capture: Captured packet stream.
        :param Scapy proto_l: Required IP protocol. Default protocol is UDP.
        """
        ip_proto = IP
        if self.af == AF_INET6:
            ip_proto = IPv6
        self.logger.info("Verifying capture on interface %s" % dst_if.name)
        last_info = dict()
        for i in self.interfaces:
            last_info[i.sw_if_index] = None
        dst_sw_if_index = dst_if.sw_if_index
        for packet in capture:
            try:
                ip_received = packet[ip_proto]
                proto_received = packet[proto_l]
                payload_info = self.payload_to_info(packet[Raw])
                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
                ip_saved = saved_packet[ip_proto]
                proto_saved = saved_packet[proto_l]
                # Check standard fields
                self.assertEqual(ip_received.src, ip_saved.src)
                self.assertEqual(ip_received.dst, ip_saved.dst)
                self.assertEqual(proto_received.sport, proto_saved.sport)
                self.assertEqual(proto_received.dport, proto_saved.dport)
            except BaseException:
                self.logger.error(ppp("Unexpected or invalid packet:", packet))
                raise
        for i in self.interfaces:
            remaining_packet = self.get_next_packet_info_for_interface2(
                i.sw_if_index, dst_sw_if_index, last_info[i.sw_if_index])
            self.assertTrue(remaining_packet is None,
                            "Interface %s: Packet expected from interface %s "
                            "didn't arrive" % (dst_if.name, i.name))

    def create_classify_table(self, key, mask, data_offset=0):
        """Create Classify Table

        :param str key: key for classify table (ex, ACL name).
        :param str mask: mask value for interested traffic.
        :param int data_offset:
        """
        mask_match, mask_match_len = self._resolve_mask_match(mask)
        r = self.vapi.classify_add_del_table(
            is_add=1,
            mask=mask_match,
            mask_len=mask_match_len,
            match_n_vectors=(len(mask) - 1) // 32 + 1,
            miss_next_index=0,
            current_data_flag=1,
            current_data_offset=data_offset)
        self.assertIsNotNone(r, 'No response msg for add_del_table')
        self.acl_tbl_idx[key] = r.new_table_index

    def create_classify_session(self, table_index, match, pbr_option=0,
                                vrfid=0, is_add=1):
        """Create Classify Session

        :param int table_index: table index to identify classify table.
        :param str match: matched value for interested traffic.
        :param int pbr_option: enable/disable PBR feature.
        :param int vrfid: VRF id.
        :param int is_add: option to configure classify session.
            - create(1) or delete(0)
        """
        mask_match, mask_match_len = self._resolve_mask_match(match)
        r = self.vapi.classify_add_del_session(
            is_add=is_add,
            table_index=table_index,
            match=mask_match,
            match_len=mask_match_len,
            opaque_index=0,
            action=pbr_option,
            metadata=vrfid)
        self.assertIsNotNone(r, 'No response msg for add_del_session')

    def input_acl_set_interface(self, intf, table_index, is_add=1):
        """Configure Input ACL interface

        :param VppInterface intf: Interface to apply Input ACL feature.
        :param int table_index: table index to identify classify table.
        :param int is_add: option to configure classify session.
            - enable(1) or disable(0)
        """
        r = None
        if self.af == AF_INET:
            r = self.vapi.input_acl_set_interface(
                is_add,
                intf.sw_if_index,
                ip4_table_index=table_index)
        elif self.af == AF_INET6:
            r = self.vapi.input_acl_set_interface(
                is_add,
                intf.sw_if_index,
                ip6_table_index=table_index)
        else:
            r = self.vapi.input_acl_set_interface(
                is_add,
                intf.sw_if_index,
                l2_table_index=table_index)
        self.assertIsNotNone(r, 'No response msg for acl_set_interface')

    def output_acl_set_interface(self, intf, table_index, is_add=1):
        """Configure Output ACL interface

        :param VppInterface intf: Interface to apply Output ACL feature.
        :param int table_index: table index to identify classify table.
        :param int is_add: option to configure classify session.
            - enable(1) or disable(0)
        """
        r = None
        if self.af == AF_INET:
            r = self.vapi.output_acl_set_interface(
                is_add,
                intf.sw_if_index,
                ip4_table_index=table_index)
        elif self.af == AF_INET6:
            r = self.vapi.output_acl_set_interface(
                is_add,
                intf.sw_if_index,
                ip6_table_index=table_index)
        else:
            r = self.vapi.output_acl_set_interface(
                is_add,
                intf.sw_if_index,
                l2_table_index=table_index)
        self.assertIsNotNone(r, 'No response msg for acl_set_interface')

    def config_pbr_fib_entry(self, intf, is_add=1):
        """Configure fib entry to route traffic toward PBR VRF table

        :param VppInterface intf: destination interface to be routed for PBR.

        """
        addr_len = 24
        self.vapi.ip_add_del_route(dst_address=intf.local_ip4,
                                   dst_address_length=addr_len,
                                   next_hop_address=intf.remote_ip4,
                                   table_id=self.pbr_vrfid, is_add=is_add)

    def verify_vrf(self, vrf_id):
        """
        Check if the FIB table / VRF ID is configured.

        :param int vrf_id: The FIB table / VRF ID to be verified.
        :return: 1 if the FIB table / VRF ID is configured, otherwise return 0.
        """
        ip_fib_dump = self.vapi.ip_route_dump(vrf_id, False)
        vrf_count = len(ip_fib_dump)
        if vrf_count == 0:
            self.logger.info("IPv4 VRF ID %d is not configured" % vrf_id)
            return 0
        else:
            self.logger.info("IPv4 VRF ID %d is configured" % vrf_id)
            return 1
