import os
import shutil
import socket
from socket import inet_pton, inet_ntop
import struct
import time
from traceback import format_exc, format_stack
from sh import tshark
from pathlib import Path

from config import config
from scapy.utils import wrpcap, rdpcap, PcapReader
from scapy.plist import PacketList
from vpp_interface import VppInterface
from vpp_papi import VppEnum

from scapy.layers.l2 import Ether, ARP
from scapy.layers.inet6 import (
    IPv6,
    ICMPv6ND_NS,
    ICMPv6ND_NA,
    ICMPv6NDOptSrcLLAddr,
    ICMPv6NDOptDstLLAddr,
    ICMPv6ND_RA,
    RouterAlert,
    IPv6ExtHdrHopByHop,
)
from util import ppp, ppc, UnexpectedPacketError
from scapy.utils6 import in6_getnsma, in6_getnsmac, in6_ismaddr


class CaptureTimeoutError(Exception):
    """Exception raised if capture or packet doesn't appear within timeout"""

    pass


def is_ipv6_misc(p):
    """Is packet one of uninteresting IPv6 broadcasts?"""
    if p.haslayer(ICMPv6ND_RA):
        if in6_ismaddr(p[IPv6].dst):
            return True
    if p.haslayer(IPv6ExtHdrHopByHop):
        for o in p[IPv6ExtHdrHopByHop].options:
            if isinstance(o, RouterAlert):
                return True
    return False


class VppPGInterface(VppInterface):
    """
    VPP packet-generator interface
    """

    @property
    def pg_index(self):
        """packet-generator interface index assigned by VPP"""
        return self._pg_index

    @property
    def gso_enabled(self):
        """gso enabled on packet-generator interface"""
        if self._gso_enabled == 0:
            return "gso-disabled"
        return "gso-enabled"

    @property
    def gso_size(self):
        """gso size on packet-generator interface"""
        return self._gso_size

    @property
    def coalesce_is_enabled(self):
        """coalesce enabled on packet-generator interface"""
        if self._coalesce_enabled == 0:
            return "coalesce-disabled"
        return "coalesce-enabled"

    @property
    def out_path(self):
        """pcap file path - captured packets"""
        return self._out_path

    def get_in_path(self, worker):
        """pcap file path - injected packets"""
        if worker is not None:
            return "%s/pg%u_wrk%u_in.pcap" % (self.test.tempdir, self.pg_index, worker)
        return "%s/pg%u_in.pcap" % (self.test.tempdir, self.pg_index)

    @property
    def capture_cli(self):
        """CLI string to start capture on this interface"""
        return self._capture_cli

    def get_cap_name(self, worker=None):
        """return capture name for this interface and given worker"""
        if worker is not None:
            return self._cap_name + "-worker%d" % worker
        return self._cap_name

    def get_input_cli(self, nb_replays=None, worker=None):
        """return CLI string to load the injected packets"""
        input_cli = "packet-generator new pcap %s source pg%u name %s" % (
            self.get_in_path(worker),
            self.pg_index,
            self.get_cap_name(worker),
        )
        if nb_replays is not None:
            return "%s limit %d" % (input_cli, nb_replays)
        if worker is not None:
            return "%s worker %d" % (input_cli, worker)
        return input_cli

    @property
    def in_history_counter(self):
        """Self-incrementing counter used when renaming old pcap files"""
        v = self._in_history_counter
        self._in_history_counter += 1
        return v

    @property
    def out_history_counter(self):
        """Self-incrementing counter used when renaming old pcap files"""
        v = self._out_history_counter
        self._out_history_counter += 1
        return v

    def __init__(self, test, pg_index, gso, gso_size, mode):
        """Create VPP packet-generator interface"""
        super().__init__(test)

        r = test.vapi.pg_create_interface_v2(pg_index, gso, gso_size, mode)
        self.set_sw_if_index(r.sw_if_index)

        self._in_history_counter = 0
        self._out_history_counter = 0
        self._out_assert_counter = 0
        self._pg_index = pg_index
        self._gso_enabled = gso
        self._gso_size = gso_size
        self._coalesce_enabled = 0
        self._out_file = "pg%u_out.pcap" % self.pg_index
        self._out_path = self.test.tempdir + "/" + self._out_file
        self._capture_cli = "packet-generator capture pg%u pcap %s" % (
            self.pg_index,
            self.out_path,
        )
        self._cap_name = "pcap%u-sw_if_index-%s" % (self.pg_index, self.sw_if_index)

    def remove_vpp_config(self):
        """delete Pg interface"""
        self.disable_capture()
        self.test.vapi.pg_delete_interface(sw_if_index=self.sw_if_index)

    def link_pcap_file(self, path, direction, counter):
        if not config.keep_pcaps:
            return
        filename = os.path.basename(path)
        test_name = (
            self.test_name
            if hasattr(self, "test_name")
            else f"suite{self.test.__name__}"
        )
        name = f"{self.test.tempdir}/{test_name}.[timestamp:{time.time():.8f}].{self.name}-{direction}-{counter:04}.{filename}"
        if os.path.isfile(name):
            self.test.logger.debug(
                f"Skipping hard link creation: {name} already exists!"
            )
            return
        try:
            if os.path.isfile(path):
                self.test.logger.debug(f"Creating hard link {path}->{name}")
                os.link(path, name)
        except OSError:
            self.test.logger.debug(
                f"OSError: Could not create hard link {path}->{name}"
            )

    def remove_old_pcap_file(self, path):
        self.wait_for_pg_stop()
        self.test.unlink_testcase_file(self.test, Path(path))
        return

    def decode_pcap_files(self, pcap_dir, filename_prefix):
        # Generate tshark packet trace of testcase pcap files
        pg_decode = f"{pcap_dir}/pcap-decode-{filename_prefix}.txt"
        if os.path.isfile(pg_decode):
            self.test.logger.debug(
                f"The pg streams decode file already exists: {pg_decode}"
            )
            return
        self.test.logger.debug(
            f"Generating testcase pg streams decode file: {pg_decode}"
        )
        ts_opts = "-Vxr"
        for p in sorted(Path(pcap_dir).glob(f"{filename_prefix}*.pcap")):
            self.test.logger.debug(f"Decoding {p}")
            with open(f"{pg_decode}", "a", buffering=1) as f:
                print(f"tshark {ts_opts} {p}", file=f)
                tshark(ts_opts, f"{p}", _out=f)
                print("", file=f)

    def enable_capture(self):
        """Enable capture on this packet-generator interface
        of at most n packets.
        If n < 0, this is no limit
        """
        # disable the capture to flush the capture
        self.disable_capture()
        self.remove_old_pcap_file(self.out_path)
        # FIXME this should be an API, but no such exists atm
        self.test.vapi.cli(self.capture_cli)
        self._pcap_reader = None

    def disable_capture(self):
        self.test.vapi.cli("%s disable" % self.capture_cli)

    def coalesce_enable(self):
        """Enable packet coalesce on this packet-generator interface"""
        self._coalesce_enabled = 1
        self.test.vapi.pg_interface_enable_disable_coalesce(self.sw_if_index, 1)

    def coalesce_disable(self):
        """Disable packet coalesce on this packet-generator interface"""
        self._coalesce_enabled = 0
        self.test.vapi.pg_interface_enable_disable_coalesce(self.sw_if_index, 0)

    def add_stream(self, pkts, nb_replays=None, worker=None):
        """
        Add a stream of packets to this packet-generator

        :param pkts: iterable packets

        """
        in_pcap = self.get_in_path(worker)
        if os.path.isfile(in_pcap):
            self.remove_old_pcap_file(in_pcap)
        wrpcap(in_pcap, pkts)
        self.test.register_pcap(self, worker)
        # FIXME this should be an API, but no such exists atm
        self.test.vapi.cli(self.get_input_cli(nb_replays, worker))
        self.link_pcap_file(self.get_in_path(worker), "inp", self.in_history_counter)

    def generate_debug_aid(self, kind):
        """Create a hardlink to the out file with a counter and a file
        containing stack trace to ease debugging in case of multiple capture
        files present."""
        self.test.logger.debug("Generating debug aid for %s on %s" % (kind, self._name))
        link_path, stack_path = [
            "%s/debug_%s_%s_%s.%s"
            % (self.test.tempdir, self._name, self._out_assert_counter, kind, suffix)
            for suffix in ["pcap", "stack"]
        ]
        os.link(self.out_path, link_path)
        with open(stack_path, "w") as f:
            f.writelines(format_stack())
        self._out_assert_counter += 1

    def _get_capture(self, timeout, filter_out_fn=is_ipv6_misc):
        """Helper method to get capture and filter it"""
        try:
            if not self.wait_for_capture_file(timeout):
                return None
            output = rdpcap(self.out_path)
            self.test.logger.debug(f"Capture has {len(output.res)} packets")
        except:
            self.test.logger.debug(
                "Exception in scapy.rdpcap (%s): %s" % (self.out_path, format_exc())
            )
            return None
        before = len(output.res)
        if filter_out_fn:
            output.res = [p for p in output.res if not filter_out_fn(p)]
        removed = before - len(output.res)
        if removed:
            self.test.logger.debug(
                "Filtered out %s packets from capture (returning %s)"
                % (removed, len(output.res))
            )
        return output

    def get_capture(
        self, expected_count=None, remark=None, timeout=1, filter_out_fn=is_ipv6_misc
    ):
        """Get captured packets

        :param expected_count: expected number of packets to capture, if None,
                               then self.test.packet_count_for_dst_pg_idx is
                               used to lookup the expected count
        :param remark: remark printed into debug logs
        :param timeout: how long to wait for packets
        :param filter_out_fn: filter applied to each packet, packets for which
                              the filter returns True are removed from capture
        :returns: iterable packets
        """
        remaining_time = timeout
        capture = None
        name = self.name if remark is None else "%s (%s)" % (self.name, remark)
        based_on = "based on provided argument"
        if expected_count is None:
            expected_count = self.test.get_packet_count_for_if_idx(self.sw_if_index)
            based_on = "based on stored packet_infos"
            if expected_count == 0:
                raise Exception(
                    "Internal error, expected packet count for %s is 0!" % name
                )
        self.test.logger.debug(
            "Expecting to capture %s (%s) packets on %s"
            % (expected_count, based_on, name)
        )
        while remaining_time > 0:
            before = time.time()
            capture = self._get_capture(remaining_time, filter_out_fn)
            elapsed_time = time.time() - before
            if capture:
                if len(capture.res) == expected_count:
                    # bingo, got the packets we expected
                    return capture
                elif len(capture.res) > expected_count:
                    self.test.logger.error(
                        ppc(
                            f"Unexpected packets captured, got {len(capture.res)}, expected {expected_count}:",
                            capture,
                        )
                    )
                    break
                else:
                    self.test.logger.debug(
                        "Partial capture containing %s "
                        "packets doesn't match expected "
                        "count %s (yet?)" % (len(capture.res), expected_count)
                    )
            elif expected_count == 0:
                # bingo, got None as we expected - return empty capture
                return PacketList()
            remaining_time -= elapsed_time
        if capture:
            self.generate_debug_aid("count-mismatch")
            if len(capture) > 0 and 0 == expected_count:
                rem = f"\n{remark}" if remark else ""
                raise UnexpectedPacketError(
                    capture[0],
                    f"\n({len(capture)} packets captured in total){rem} on {name}",
                )
            msg = f"Captured packets mismatch, captured {len(capture.res)} packets, expected {expected_count} packets on {name}:"
            raise Exception(f"{ppc(msg, capture)}")
        else:
            if 0 == expected_count:
                return
            raise Exception(f"No packets captured on {name} (timeout = {timeout}s)")

    def assert_nothing_captured(
        self, timeout=1, remark=None, filter_out_fn=is_ipv6_misc
    ):
        """Assert that nothing unfiltered was captured on interface

        :param remark: remark printed into debug logs
        :param filter_out_fn: filter applied to each packet, packets for which
                              the filter returns True are removed from capture
        """
        capture = self.get_capture(
            0, timeout=timeout, remark=remark, filter_out_fn=filter_out_fn
        )
        if not capture or len(capture.res) == 0:
            # junk filtered out, we're good
            return

    def wait_for_pg_stop(self):
        # wait till packet-generator is stopped
        # "show packet-generator" while it is still running gives this:
        # Name               Enabled        Count     Parameters
        # pcap0-sw_if_inde     Yes           64       limit 64, ...
        #
        # also have a 5-minute timeout just in case things go terribly wrong...
        deadline = time.time() + 300
        while self.test.vapi.cli("show packet-generator").find("Yes") != -1:
            self._test.sleep(0.01)  # yield
            if time.time() > deadline:
                self.test.logger.debug("Timeout waiting for pg to stop")
                break

    def wait_for_capture_file(self, timeout=1):
        """
        Wait until pcap capture file appears

        :param timeout: How long to wait for the packet (default 1s)

        :returns: True/False if the file is present or appears within timeout
        """
        self.wait_for_pg_stop()
        deadline = time.time() + timeout
        if not os.path.isfile(self.out_path):
            self.test.logger.debug(
                f"Waiting for capture file {self.out_path} to appear, timeout is {timeout}s\n"
                f"{' '.join(format_stack(limit=10))}"
            )
        else:
            self.test.logger.debug("Capture file %s already exists" % self.out_path)
            self.link_pcap_file(self.out_path, "out", self.out_history_counter)
            return True
        while time.time() < deadline:
            if os.path.isfile(self.out_path):
                break
            self._test.sleep(0)  # yield
        if os.path.isfile(self.out_path):
            self.test.logger.debug(
                "Capture file appeared after %fs" % (time.time() - (deadline - timeout))
            )
        else:
            self.test.logger.debug("Timeout - capture file still nowhere")
            return False
        self.link_pcap_file(self.out_path, "out", self.out_history_counter)
        return True

    def verify_enough_packet_data_in_pcap(self):
        """
        Check if enough data is available in file handled by internal pcap
        reader so that a whole packet can be read.

        :returns: True if enough data present, else False
        """
        orig_pos = self._pcap_reader.f.tell()  # save file position
        enough_data = False
        # read packet header from pcap
        packet_header_size = 16
        caplen = None
        end_pos = None
        hdr = self._pcap_reader.f.read(packet_header_size)
        if len(hdr) == packet_header_size:
            # parse the capture length - caplen
            sec, usec, caplen, wirelen = struct.unpack(
                self._pcap_reader.endian + "IIII", hdr
            )
            self._pcap_reader.f.seek(0, 2)  # seek to end of file
            end_pos = self._pcap_reader.f.tell()  # get position at end
            if end_pos >= orig_pos + len(hdr) + caplen:
                enough_data = True  # yay, we have enough data
        self._pcap_reader.f.seek(orig_pos, 0)  # restore original position
        return enough_data

    def wait_for_packet(self, timeout, filter_out_fn=is_ipv6_misc):
        """
        Wait for next packet captured with a timeout

        :param timeout: How long to wait for the packet

        :returns: Captured packet if no packet arrived within timeout
        :raises Exception: if no packet arrives within timeout
        """
        deadline = time.time() + timeout
        if self._pcap_reader is None:
            if not self.wait_for_capture_file(timeout):
                raise CaptureTimeoutError(
                    "Capture file %s did not appear within timeout" % self.out_path
                )
            while time.time() < deadline:
                try:
                    self._pcap_reader = PcapReader(self.out_path)
                    break
                except:
                    self.test.logger.debug(
                        "Exception in scapy.PcapReader(%s): %s"
                        % (self.out_path, format_exc())
                    )
        if not self._pcap_reader:
            raise CaptureTimeoutError(
                "Capture file %s did not appear within timeout" % self.out_path
            )

        poll = False
        if timeout > 0:
            self.test.logger.debug("Waiting for packet")
        else:
            poll = True
            self.test.logger.debug("Polling for packet")
        while time.time() < deadline or poll:
            if not self.verify_enough_packet_data_in_pcap():
                self._test.sleep(0)  # yield
                poll = False
                continue
            p = self._pcap_reader.recv()
            if p is not None:
                if filter_out_fn is not None and filter_out_fn(p):
                    self.test.logger.debug(
                        "Packet received after %ss was filtered out"
                        % (time.time() - (deadline - timeout))
                    )
                else:
                    self.test.logger.debug(
                        "Packet received after %fs"
                        % (time.time() - (deadline - timeout))
                    )
                    return p
            self._test.sleep(0)  # yield
            poll = False
        self.test.logger.debug(f"Timeout ({timeout}) - no packets received")
        raise CaptureTimeoutError(f"Packet didn't arrive within timeout ({timeout})")

    def create_arp_req(self):
        """Create ARP request applicable for this interface"""
        return Ether(dst="ff:ff:ff:ff:ff:ff", src=self.remote_mac) / ARP(
            op=ARP.who_has,
            pdst=self.local_ip4,
            psrc=self.remote_ip4,
            hwsrc=self.remote_mac,
        )

    def create_ndp_req(self, addr=None):
        """Create NDP - NS applicable for this interface"""
        if not addr:
            addr = self.local_ip6
        nsma = in6_getnsma(inet_pton(socket.AF_INET6, addr))
        d = inet_ntop(socket.AF_INET6, nsma)

        return (
            Ether(dst=in6_getnsmac(nsma))
            / IPv6(dst=d, src=self.remote_ip6)
            / ICMPv6ND_NS(tgt=addr)
            / ICMPv6NDOptSrcLLAddr(lladdr=self.remote_mac)
        )

    def resolve_arp(self, pg_interface=None):
        """Resolve ARP using provided packet-generator interface

        :param pg_interface: interface used to resolve, if None then this
            interface is used

        """
        if pg_interface is None:
            pg_interface = self
        self.test.logger.info(
            "Sending ARP request for %s on port %s"
            % (self.local_ip4, pg_interface.name)
        )
        arp_req = self.create_arp_req()
        pg_interface.add_stream(arp_req)
        pg_interface.enable_capture()
        self.test.pg_start()
        self.test.logger.info(self.test.vapi.cli("show trace"))
        try:
            captured_packet = pg_interface.wait_for_packet(1)
        except:
            self.test.logger.info("No ARP received on port %s" % pg_interface.name)
            return
        arp_reply = captured_packet.copy()  # keep original for exception
        try:
            if arp_reply[ARP].op == ARP.is_at:
                self.test.logger.info(
                    "VPP %s MAC address is %s " % (self.name, arp_reply[ARP].hwsrc)
                )
                self._local_mac = arp_reply[ARP].hwsrc
            else:
                self.test.logger.info("No ARP received on port %s" % pg_interface.name)
        except:
            self.test.logger.error(
                ppp("Unexpected response to ARP request:", captured_packet)
            )
            raise

    def resolve_ndp(self, pg_interface=None, timeout=1, link_layer=False):
        """Resolve NDP using provided packet-generator interface

        :param pg_interface: interface used to resolve, if None then this
            interface is used
        :param timeout: how long to wait for response before giving up
        :param link_layer: resolve for global address if False (default)
            or for link-layer address if True

        """
        if pg_interface is None:
            pg_interface = self
        addr = self.local_ip6_ll if link_layer else self.local_ip6
        self.test.logger.info(
            "Sending NDP request for %s on port %s" % (addr, pg_interface.name)
        )
        ndp_req = self.create_ndp_req(addr)
        pg_interface.add_stream(ndp_req)
        pg_interface.enable_capture()
        self.test.pg_start()
        now = time.time()
        deadline = now + timeout
        # Enabling IPv6 on an interface can generate more than the
        # ND reply we are looking for (namely MLD). So loop through
        # the replies to look for want we want.
        while now < deadline:
            try:
                captured_packet = pg_interface.wait_for_packet(
                    deadline - now, filter_out_fn=None
                )
            except:
                self.test.logger.error("Timeout while waiting for NDP response")
                raise
            ndp_reply = captured_packet.copy()  # keep original for exception
            try:
                ndp_na = ndp_reply[ICMPv6ND_NA]
                opt = ndp_na[ICMPv6NDOptDstLLAddr]
                self.test.logger.info(
                    "VPP %s MAC address is %s " % (self.name, opt.lladdr)
                )
                self._local_mac = opt.lladdr
                self.test.logger.debug(self.test.vapi.cli("show trace"))
                # we now have the MAC we've been after
                return
            except:
                self.test.logger.info(
                    ppp("Unexpected response to NDP request:", captured_packet)
                )
            now = time.time()

        self.test.logger.debug(self.test.vapi.cli("show trace"))
        raise Exception("Timeout while waiting for NDP response")
