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 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")
