# SPDX-License-Identifier: GPL-2.0

import ipaddress
import os
import sys
import time
import json
from pathlib import Path
from lib.py import KsftSkipEx, KsftXfailEx
from lib.py import ksft_pr, ksft_setup, wait_file
from lib.py import cmd, ethtool, ip, CmdExitFailure
from lib.py import NetNS, NetdevSimDev, UserNetNS
from .remote import Remote
from . import bpftool, RtnlFamily, Netlink


class NetDrvEnvBase:
    """
    Base class for a NIC / host environments

    Attributes:
      test_dir: Path to the source directory of the test
      net_lib_dir: Path to the net/lib directory
    """
    def __init__(self, src_path):
        self.src_path = Path(src_path)
        self.test_dir = self.src_path.parent.resolve()
        self.net_lib_dir = (Path(__file__).parent / "../../../../net/lib").resolve()

        self.env = self._load_env_file()

        # Following attrs must be set be inheriting classes
        self.dev = None
        self.ifname = None

    def _load_env_file(self):
        env = os.environ.copy()

        src_dir = Path(self.src_path).parent.resolve()
        if not (src_dir / "net.config").exists():
            return ksft_setup(env)

        with open((src_dir / "net.config").as_posix(), 'r') as fp:
            for line in fp.readlines():
                full_file = line
                # Strip comments
                pos = line.find("#")
                if pos >= 0:
                    line = line[:pos]
                line = line.strip()
                if not line:
                    continue
                pair = line.split('=', maxsplit=1)
                if len(pair) != 2:
                    raise Exception("Can't parse configuration line:", full_file)
                env[pair[0]] = pair[1]
        return ksft_setup(env)

    def __del__(self):
        pass

    def _print_dev_info(self):
        """
        Show whether the test ran on real hardware or netdevsim.
        Useful to confirm when results are shared on the mailing list.
        """
        driver = "unknown"
        try:
            info = ethtool(f"-i {self.ifname}").stdout
            for line in info.splitlines():
                if line.startswith("driver:"):
                    driver = line.split(':', 1)[1].strip() or driver
                    break
        except (CmdExitFailure, FileNotFoundError):
            pass
        ksft_pr(f"Interface: {self.ifname}, driver: {driver}")

    def __enter__(self):
        ip(f"link set dev {self.dev['ifname']} up")
        wait_file(f"/sys/class/net/{self.dev['ifname']}/carrier",
                  lambda x: x.strip() == "1")

        return self

    def __exit__(self, ex_type, ex_value, ex_tb):
        """
        __exit__ gets called at the end of a "with" block.
        """
        self.__del__()


class NetDrvEnv(NetDrvEnvBase):
    """
    Class for a single NIC / host env, with no remote end
    """
    def __init__(self, src_path, nsim_test=None, **kwargs):
        super().__init__(src_path)

        self._ns = None

        if 'NETIF' in self.env:
            if nsim_test is True:
                raise KsftXfailEx("Test only works on netdevsim")

            self.dev = ip("-d link show dev " + self.env['NETIF'], json=True)[0]
        else:
            if nsim_test is False:
                raise KsftXfailEx("Test does not work on netdevsim")

            self._ns = NetdevSimDev(**kwargs)
            self.dev = self._ns.nsims[0].dev
        self.ifname = self.dev['ifname']
        self.ifindex = self.dev['ifindex']
        self._print_dev_info()

    def __del__(self):
        if self._ns:
            self._ns.remove()
            self._ns = None


class NetDrvEpEnv(NetDrvEnvBase):
    """
    Class for an environment with a local device and "remote endpoint"
    which can be used to send traffic in.

    For local testing it creates two network namespaces and a pair
    of netdevsim devices.
    """

    # Network prefixes used for local tests
    nsim_v4_pfx = "192.0.2."
    nsim_v6_pfx = "2001:db8::"

    def __init__(self, src_path, nsim_test=None, queue_count=None):
        super().__init__(src_path)

        self._stats_settle_time = None
        self._queue_count = queue_count

        # Things we try to destroy
        self.remote = None
        # These are for local testing state
        self._netns = None
        self._ns = None
        self._ns_peer = None

        self.addr_v        = { "4": None, "6": None }
        self.remote_addr_v = { "4": None, "6": None }

        if "NETIF" in self.env:
            if nsim_test is True:
                raise KsftXfailEx("Test only works on netdevsim")
            self._check_env()

            self.dev = ip("-d link show dev " + self.env['NETIF'], json=True)[0]

            self.addr_v["4"] = self.env.get("LOCAL_V4")
            self.addr_v["6"] = self.env.get("LOCAL_V6")
            self.remote_addr_v["4"] = self.env.get("REMOTE_V4")
            self.remote_addr_v["6"] = self.env.get("REMOTE_V6")
            kind = self.env["REMOTE_TYPE"]
            args = self.env["REMOTE_ARGS"]
        else:
            if nsim_test is False:
                raise KsftXfailEx("Test does not work on netdevsim")

            self.create_local()

            self.dev = self._ns.nsims[0].dev

            self.addr_v["4"] = self.nsim_v4_pfx + "1"
            self.addr_v["6"] = self.nsim_v6_pfx + "1"
            self.remote_addr_v["4"] = self.nsim_v4_pfx + "2"
            self.remote_addr_v["6"] = self.nsim_v6_pfx + "2"
            kind = "netns"
            args = self._netns.name

        self.remote = Remote(kind, args, src_path)

        self.set_ipver("6" if self.addr_v["6"] else "4")

        self.ifname = self.dev['ifname']
        self.ifindex = self.dev['ifindex']
        self._print_dev_info()

        # resolve remote interface name
        self.remote_ifname = self.resolve_remote_ifc()
        self.remote_dev = ip("-d link show dev " + self.remote_ifname,
                             host=self.remote, json=True)[0]
        self.remote_ifindex = self.remote_dev['ifindex']

        self._required_cmd = {}

    def create_local(self):
        nsim_kwargs = {}
        if self._queue_count:
            nsim_kwargs["queue_count"] = self._queue_count

        self._netns = NetNS()
        self._ns = NetdevSimDev(**nsim_kwargs)
        self._ns_peer = NetdevSimDev(ns=self._netns, **nsim_kwargs)

        with open("/proc/self/ns/net") as nsfd0, \
             open("/var/run/netns/" + self._netns.name) as nsfd1:
            ifi0 = self._ns.nsims[0].ifindex
            ifi1 = self._ns_peer.nsims[0].ifindex
            NetdevSimDev.ctrl_write('link_device',
                                    f'{nsfd0.fileno()}:{ifi0} {nsfd1.fileno()}:{ifi1}')

        ip(f"   addr add dev {self._ns.nsims[0].ifname} {self.nsim_v4_pfx}1/24")
        ip(f"-6 addr add dev {self._ns.nsims[0].ifname} {self.nsim_v6_pfx}1/64 nodad")
        ip(f"   link set dev {self._ns.nsims[0].ifname} up")

        ip(f"   addr add dev {self._ns_peer.nsims[0].ifname} {self.nsim_v4_pfx}2/24", ns=self._netns)
        ip(f"-6 addr add dev {self._ns_peer.nsims[0].ifname} {self.nsim_v6_pfx}2/64 nodad", ns=self._netns)
        ip(f"   link set dev {self._ns_peer.nsims[0].ifname} up", ns=self._netns)

    def _check_env(self):
        vars_needed = [
            ["LOCAL_V4", "LOCAL_V6"],
            ["REMOTE_V4", "REMOTE_V6"],
            ["REMOTE_TYPE"],
            ["REMOTE_ARGS"]
        ]
        missing = []

        for choice in vars_needed:
            for entry in choice:
                if entry in self.env:
                    break
            else:
                missing.append(choice)
        # Make sure v4 / v6 configs are symmetric
        if ("LOCAL_V6" in self.env) != ("REMOTE_V6" in self.env):
            missing.append(["LOCAL_V6", "REMOTE_V6"])
        if ("LOCAL_V4" in self.env) != ("REMOTE_V4" in self.env):
            missing.append(["LOCAL_V4", "REMOTE_V4"])
        if missing:
            raise Exception("Invalid environment, missing configuration:", missing,
                            "Please see tools/testing/selftests/drivers/net/README.rst")

    def resolve_remote_ifc(self):
        v4 = v6 = None
        if self.remote_addr_v["4"]:
            v4 = ip("addr show to " + self.remote_addr_v["4"], json=True, host=self.remote)
        if self.remote_addr_v["6"]:
            v6 = ip("addr show to " + self.remote_addr_v["6"], json=True, host=self.remote)
        if v4 and v6 and v4[0]["ifname"] != v6[0]["ifname"]:
            raise Exception("Can't resolve remote interface name, v4 and v6 don't match")
        if (v4 and len(v4) > 1) or (v6 and len(v6) > 1):
            raise Exception("Can't resolve remote interface name, multiple interfaces match")
        return v6[0]["ifname"] if v6 else v4[0]["ifname"]

    def __del__(self):
        if self._ns:
            self._ns.remove()
            self._ns = None
        if self._ns_peer:
            self._ns_peer.remove()
            self._ns_peer = None
        if self._netns:
            del self._netns
            self._netns = None
        if self.remote:
            del self.remote
            self.remote = None

    def require_ipver(self, ipver):
        if not self.addr_v[ipver] or not self.remote_addr_v[ipver]:
            raise KsftSkipEx(f"Test requires IPv{ipver} connectivity")

    def set_ipver(self, ipver):
        """
        Modify the IP version used by the generic address fields.
        """
        if ipver == getattr(self, "addr_ipver", None):
            return

        self.require_ipver(ipver)

        self.addr_ipver = ipver
        self.addr = self.addr_v[ipver]
        self.remote_addr = self.remote_addr_v[ipver]

        # Bracketed addresses, some commands need IPv6 to be inside []
        self.baddr = (f"[{self.addr_v['6']}]" if ipver == "6"
                      else self.addr_v["4"])
        self.remote_baddr = (f"[{self.remote_addr_v['6']}]" if ipver == "6"
                             else self.remote_addr_v["4"])

    def require_nsim(self, nsim_test=True):
        """Require or exclude netdevsim for this test"""
        if nsim_test and self._ns is None:
            raise KsftXfailEx("Test only works on netdevsim")
        if nsim_test is False and self._ns is not None:
            raise KsftXfailEx("Test does not work on netdevsim")

    def get_local_nsim_dev(self):
        """Returns the local netdevsim device or None.
           Using this method is discouraged, as it makes tests nsim-specific.
           Standard interfaces available on all HW should ideally be used.
           This method is intended for the few cases where nsim-specific
           assertions need to be verified which cannot be verified otherwise.
        """
        return self._ns

    def _require_cmd(self, comm, key, host=None):
        cached = self._required_cmd.get(comm, {})
        if cached.get(key) is None:
            cached[key] = cmd("command -v -- " + comm, fail=False,
                              shell=True, host=host).ret == 0
        self._required_cmd[comm] = cached
        return cached[key]

    def require_cmd(self, comm, local=True, remote=False):
        if local:
            if not self._require_cmd(comm, "local"):
                raise KsftSkipEx("Test requires command: " + comm)
        if remote:
            if not self._require_cmd(comm, "remote", host=self.remote):
                raise KsftSkipEx("Test requires (remote) command: " + comm)

    def wait_hw_stats_settle(self):
        """
        Wait for HW stats to become consistent, some devices DMA HW stats
        periodically so events won't be reflected until next sync.
        Good drivers will tell us via ethtool what their sync period is.
        """
        if self._stats_settle_time is None:
            data = {}
            try:
                data = ethtool("-c " + self.ifname, json=True)[0]
            except CmdExitFailure as e:
                if "Operation not supported" not in e.cmd.stderr:
                    raise

            self._stats_settle_time = \
                1.25 * data.get('stats-block-usecs', 20000) / 1000 / 1000

        time.sleep(self._stats_settle_time)


class NetDrvContEnv(NetDrvEpEnv):
    """
    Class for an environment with a netkit pair setup for forwarding traffic
    between the physical interface and a network namespace.
      NETIF           = "eth0"
      LOCAL_V6        = "2001:db8:1::1"
      REMOTE_V6       = "2001:db8:1::2"
      LOCAL_PREFIX_V6 = "2001:db8:2::0/64"

              +-----------------------------+        +------------------------------+
      dst     | INIT NS                     |        | TEST NS                      |
      2001:   | +---------------+           |        |                              |
      db8:2::2| | NETIF         |           |  bpf   |                              |
          +---|>| 2001:db8:1::1 |           |redirect| +-------------------------+  |
          |   | |               |-----------|--------|>| Netkit                  |  |
          |   | +---------------+           | _peer  | | nk_guest                |  |
          |   | +-------------+ Netkit pair |        | | fe80::2/64              |  |
          |   | | Netkit      |.............|........|>| 2001:db8:2::2/64        |  |
          |   | | nk_host     |             |        | +-------------------------+  |
          |   | | fe80::1/64  |             |        |                              |
          |   | +-------------+             |        | route:                       |
          |   |                             |        |   default                    |
          |   | route:                      |        |     via fe80::1 dev nk_guest |
          |   |   2001:db8:2::2/128         |        +------------------------------+
          |   |     via fe80::2 dev nk_host |
          |   +-----------------------------+
          |
          |   +---------------+
          |   | REMOTE        |
          +---| 2001:db8:1::2 |
              +---------------+
    """

    def __init__(self, src_path, rxqueues=1, primary_rx_redirect=False,
                 userns=False, **kwargs):
        self.netns = None
        self._userns = userns
        self.nk_host_ifname = None
        self.nk_guest_ifname = None
        self._tc_clsact_added = False
        self._tc_attached = False
        self._primary_rx_redirect_attached = False
        self._primary_rx_redirect_clsact_added = False
        self._bpf_prog_pref = None
        self._bpf_prog_id = None
        self._init_ns_attached = False
        self._remote_route_added = False
        self._old_fwd = None
        self._old_accept_ra = None

        super().__init__(src_path, **kwargs)

        self.require_ipver("6")
        local_prefix = self.env.get("LOCAL_PREFIX_V6")
        if not local_prefix:
            raise KsftSkipEx("LOCAL_PREFIX_V6 required")

        net = ipaddress.IPv6Network(local_prefix, strict=False)
        self.ipv6_prefix = str(net.network_address)
        self.nk_host_ipv6 = f"{self.ipv6_prefix}2:1"
        self.nk_guest_ipv6 = f"{self.ipv6_prefix}2:2"

        local_v6 = ipaddress.IPv6Address(self.addr_v["6"])
        if local_v6 in net:
            raise KsftSkipEx("LOCAL_V6 must not fall within LOCAL_PREFIX_V6")

        rtnl = RtnlFamily()
        rtnl.newlink(
            {
                "linkinfo": {
                    "kind": "netkit",
                    "data": {
                        "mode": "l2",
                        "policy": "forward",
                        "peer-policy": "forward",
                    },
                },
                "num-rx-queues": rxqueues,
            },
            flags=[Netlink.NLM_F_CREATE, Netlink.NLM_F_EXCL],
        )

        all_links = ip("-d link show", json=True)
        netkit_links = [link for link in all_links
                        if link.get('linkinfo', {}).get('info_kind') == 'netkit'
                        and 'UP' not in link.get('flags', [])]

        if len(netkit_links) != 2:
            raise KsftSkipEx("Failed to create netkit pair")

        netkit_links.sort(key=lambda x: x['ifindex'])
        self.nk_host_ifname = netkit_links[1]['ifname']
        self.nk_guest_ifname = netkit_links[0]['ifname']
        self.nk_host_ifindex = netkit_links[1]['ifindex']
        self.nk_guest_ifindex = netkit_links[0]['ifindex']

        self._setup_ns()
        self.attach_bpf()
        if primary_rx_redirect:
            self._attach_primary_rx_redirect_bpf()

    def __del__(self):
        if self._primary_rx_redirect_attached:
            cmd(f"tc filter del dev {self.nk_host_ifname} ingress", fail=False)
            self._primary_rx_redirect_attached = False

        if self._primary_rx_redirect_clsact_added:
            cmd(f"tc qdisc del dev {self.nk_host_ifname} clsact", fail=False)
            self._primary_rx_redirect_clsact_added = False

        if self._tc_attached:
            cmd(f"tc filter del dev {self.ifname} ingress pref {self._bpf_prog_pref}")
            self._tc_attached = False

        if self._tc_clsact_added:
            cmd(f"tc qdisc del dev {self.ifname} clsact")
            self._tc_clsact_added = False

        if self._remote_route_added:
            cmd(f"ip -6 route del {self.nk_guest_ipv6}/128",
                host=self.remote, fail=False)
            self._remote_route_added = False

        if self.nk_host_ifname:
            cmd(f"ip link del dev {self.nk_host_ifname}")
            self.nk_host_ifname = None
            self.nk_guest_ifname = None

        if self._init_ns_attached:
            cmd("ip netns del init", fail=False)
            self._init_ns_attached = False

        if self.netns:
            del self.netns
            self.netns = None

        if self._old_fwd is not None:
            with open("/proc/sys/net/ipv6/conf/all/forwarding", "w",
                      encoding="utf-8") as f:
                f.write(self._old_fwd)
            self._old_fwd = None
        if self._old_accept_ra is not None:
            with open("/proc/sys/net/ipv6/conf/all/accept_ra", "w",
                      encoding="utf-8") as f:
                f.write(self._old_accept_ra)
            self._old_accept_ra = None

        super().__del__()

    def _setup_ns(self):
        fwd_path = "/proc/sys/net/ipv6/conf/all/forwarding"
        ra_path = "/proc/sys/net/ipv6/conf/all/accept_ra"
        with open(fwd_path, encoding="utf-8") as f:
            self._old_fwd = f.read().strip()
        with open(ra_path, encoding="utf-8") as f:
            self._old_accept_ra = f.read().strip()
        with open(fwd_path, "w", encoding="utf-8") as f:
            f.write("1")
        with open(ra_path, "w", encoding="utf-8") as f:
            f.write("2")

        self.netns = UserNetNS() if self._userns else NetNS()
        cmd("ip netns attach init 1")
        self._init_ns_attached = True
        ip("netns set init 0", ns=self.netns)
        ip(f"link set dev {self.nk_guest_ifname} netns {self.netns.name}")
        nk_guest_dev = ip(f"link show dev {self.nk_guest_ifname}",
                          json=True, ns=self.netns)[0]
        self.nk_guest_ifindex = nk_guest_dev['ifindex']
        ip(f"link set dev {self.nk_host_ifname} up")
        ip(f"-6 addr add fe80::1/64 dev {self.nk_host_ifname} nodad")
        ip(f"-6 route add {self.nk_guest_ipv6}/128 via fe80::2 dev {self.nk_host_ifname}")

        ip("link set lo up", ns=self.netns)
        ip(f"link set dev {self.nk_guest_ifname} up", ns=self.netns)
        ip(f"-6 addr add fe80::2/64 dev {self.nk_guest_ifname}", ns=self.netns)
        ip(f"-6 addr add {self.nk_guest_ipv6}/64 dev {self.nk_guest_ifname} nodad", ns=self.netns)
        ip(f"-6 route add default via fe80::1 dev {self.nk_guest_ifname}", ns=self.netns)

    def _tc_ensure_clsact(self, ifname=None):
        """Ensure a clsact qdisc exists on @ifname.

        Returns True if this call added the qdisc, otherwise returns False.
        """
        if ifname is None:
            ifname = self.ifname
        qdisc = json.loads(cmd(f"tc -j qdisc show dev {ifname}").stdout)
        for q in qdisc:
            if q['kind'] == 'clsact':
                return False
        cmd(f"tc qdisc add dev {ifname} clsact")
        return True

    def _get_bpf_prog_ids(self):
        filters = json.loads(cmd(f"tc -j filter show dev {self.ifname} ingress").stdout)
        for bpf in filters:
            if 'options' not in bpf:
                continue
            if bpf['options']['bpf_name'].startswith('nk_forward.bpf'):
                return (bpf['pref'], bpf['options']['prog']['id'])
        raise Exception("Failed to get BPF prog ID")

    def _find_bss_map_id(self, prog_id):
        """Find the .bss map ID for a loaded BPF program."""
        prog_info = bpftool(f"prog show id {prog_id}", json=True)
        for map_id in prog_info.get("map_ids", []):
            map_info = bpftool(f"map show id {map_id}", json=True)
            if map_info.get("name", "").endswith("bss"):
                return map_id
        raise Exception(f"Failed to find .bss map for prog {prog_id}")

    def _find_bpf_obj(self, name):
        bpf_obj = self.test_dir / name
        if bpf_obj.exists():
            return bpf_obj
        bpf_obj = self.test_dir / "hw" / name
        if bpf_obj.exists():
            return bpf_obj
        return None

    def detach_bpf(self):
        if self._tc_attached:
            cmd(f"tc filter del dev {self.ifname} ingress pref "
                f"{self._bpf_prog_pref}", fail=False)
            self._tc_attached = False

    def attach_bpf(self):
        bpf_obj = self._find_bpf_obj("nk_forward.bpf.o")
        if not bpf_obj:
            raise KsftSkipEx("BPF prog nk_forward.bpf.o not found")

        if self._tc_ensure_clsact():
            self._tc_clsact_added = True
        cmd(f"tc filter add dev {self.ifname} ingress bpf obj {bpf_obj}"
            " sec tc/ingress direct-action")
        self._tc_attached = True

        (self._bpf_prog_pref, self._bpf_prog_id) = self._get_bpf_prog_ids()
        bss_map_id = self._find_bss_map_id(self._bpf_prog_id)

        ipv6_addr = ipaddress.IPv6Address(self.ipv6_prefix)
        ipv6_bytes = ipv6_addr.packed
        ifindex_bytes = self.nk_host_ifindex.to_bytes(4, byteorder='little')
        value = ipv6_bytes + ifindex_bytes
        value_hex = ' '.join(f'{b:02x}' for b in value)
        bpftool(f"map update id {bss_map_id} key hex 00 00 00 00 value hex {value_hex}")

    def _attach_primary_rx_redirect_bpf(self):
        """Attach BPF redirect program on the primary netkit ingress."""
        bpf_obj = self._find_bpf_obj("nk_primary_rx_redirect.bpf.o")
        if not bpf_obj:
            raise KsftSkipEx("nk_primary_rx_redirect.bpf.o not found")

        if self._tc_ensure_clsact(self.nk_host_ifname):
            self._primary_rx_redirect_clsact_added = True
        cmd(f"tc filter add dev {self.nk_host_ifname} ingress"
            f" bpf obj {bpf_obj} sec tc/ingress direct-action")
        self._primary_rx_redirect_attached = True

        ip(f"-6 route add {self.nk_guest_ipv6}/128 via {self.addr_v['6']}",
           host=self.remote)
        self._remote_route_added = True

        filters = json.loads(
            cmd(f"tc -j filter show dev {self.nk_host_ifname} ingress").stdout)
        redirect_prog_id = None
        for bpf in filters:
            if 'options' not in bpf:
                continue
            if bpf['options']['bpf_name'].startswith('nk_primary_rx_redirect'):
                redirect_prog_id = bpf['options']['prog']['id']
                break
        if redirect_prog_id is None:
            raise Exception("Failed to get primary RX redirect BPF prog ID")

        bss_map_id = self._find_bss_map_id(redirect_prog_id)
        phys_ifindex_bytes = self.ifindex.to_bytes(4, byteorder=sys.byteorder)
        value_hex = ' '.join(f'{b:02x}' for b in phys_ifindex_bytes)
        bpftool(f"map update id {bss_map_id} key hex 00 00 00 00 value hex {value_hex}")
