#!/usr/bin/env python3
""" Container integration tests """

import unittest
from config import config
from framework import VppTestCase
from asfframework import VppTestRunner
from scapy.layers.inet import UDP
from socket import AF_INET, AF_INET6
from util import L4_Conn


class Conn(L4_Conn):
    # for now same as L4_Conn
    pass


@unittest.skipUnless(config.extended, "part of extended tests")
class ContainerIntegrationTestCase(VppTestCase):
    """Container integration extended testcases"""

    @classmethod
    def setUpClass(cls):
        super(ContainerIntegrationTestCase, cls).setUpClass()
        # create pg0 and pg1
        cls.create_pg_interfaces(range(2))
        for i in cls.pg_interfaces:
            i.admin_up()
            i.config_ip4()
            i.config_ip6()
            i.resolve_arp()
            i.resolve_ndp()

    @classmethod
    def tearDownClass(cls):
        super(ContainerIntegrationTestCase, cls).tearDownClass()

    def tearDown(self):
        """Run standard test teardown and log various show commands"""
        super(ContainerIntegrationTestCase, self).tearDown()

    def show_commands_at_teardown(self):
        self.logger.info(self.vapi.cli("show ip neighbors"))

    def run_basic_conn_test(self, af, acl_side):
        """Basic connectivity test"""
        conn1 = Conn(self, self.pg0, self.pg1, af, UDP, 42001, 4242)
        conn1.send_through(0)
        # the return packets should pass
        conn1.send_through(1)

    def run_negative_conn_test(self, af, acl_side):
        """Packets with local spoofed address"""
        conn1 = Conn(self, self.pg0, self.pg1, af, UDP, 42001, 4242)
        try:
            p2 = conn1.send_through(0).command()
        except:
            # If we asserted while waiting, it's good.
            # the conn should have timed out.
            p2 = None
        self.assert_equal(p2, None, ": packet should have been dropped")

    def test_0010_basic_conn_test(self):
        """IPv4 basic connectivity test"""
        self.run_basic_conn_test(AF_INET, 0)

    def test_0011_basic_conn_test(self):
        """IPv6 basic connectivity test"""
        self.run_basic_conn_test(AF_INET6, 0)

    def test_0050_loopback_prepare_test(self):
        """Create loopbacks overlapping with remote addresses"""
        self.create_loopback_interfaces(2)
        for i in range(2):
            intf = self.lo_interfaces[i]
            intf.admin_up()
            intf.local_ip4 = self.pg_interfaces[i].remote_ip4
            intf.local_ip4_prefix_len = 32
            intf.config_ip4()
            intf.local_ip6 = self.pg_interfaces[i].remote_ip6
            intf.local_ip6_prefix_len = 128
            intf.config_ip6()

    def test_0110_basic_conn_test(self):
        """IPv4 local-spoof connectivity test"""
        self.run_negative_conn_test(AF_INET, 0)

    def test_0111_basic_conn_test(self):
        """IPv6 local-spoof connectivity test"""
        self.run_negative_conn_test(AF_INET, 1)

    def test_0200_basic_conn_test(self):
        """Configure container commands"""
        for i in range(2):
            for addr in [
                self.pg_interfaces[i].remote_ip4,
                self.pg_interfaces[i].remote_ip6,
            ]:
                self.vapi.ppcli(
                    "ip container " + addr + " " + self.pg_interfaces[i].name
                )
                self.vapi.ppcli(
                    "stn rule address "
                    + addr
                    + " interface "
                    + self.pg_interfaces[i].name
                )

    def test_0210_basic_conn_test(self):
        """IPv4 test after configuring container"""
        self.run_basic_conn_test(AF_INET, 0)

    def test_0211_basic_conn_test(self):
        """IPv6 test after configuring container"""
        self.run_basic_conn_test(AF_INET, 1)

    def test_0300_unconfigure_commands(self):
        """Unconfigure container commands"""
        for i in range(2):
            for addr in [
                self.pg_interfaces[i].remote_ip4,
                self.pg_interfaces[i].remote_ip6,
            ]:
                self.vapi.ppcli(
                    "ip container " + addr + " " + self.pg_interfaces[i].name + " del"
                )
                self.vapi.ppcli(
                    "stn rule address "
                    + addr
                    + " interface "
                    + self.pg_interfaces[i].name
                    + " del"
                )

    def test_0410_spoof_test(self):
        """IPv4 local-spoof after unconfig test"""
        self.run_negative_conn_test(AF_INET, 0)

    def test_0411_spoof_test(self):
        """IPv6 local-spoof after unconfig test"""
        self.run_negative_conn_test(AF_INET, 1)
