#!/usr/bin/env python
# SPDX-License-Identifier: GPL-2.0

import subprocess
import json as j
import random


class SkipTest(Exception):
    pass


class RandomValuePicker:
    """
    Class for storing shared buffer configuration. Can handle 3 different
    objects, pool, tcbind and portpool. Provide an interface to get random
    values for a specific object type as the follow:
      1. Pool:
         - random size

      2. TcBind:
         - random pool number
         - random threshold

      3. PortPool:
         - random threshold
    """
    def __init__(self, pools):
        self._pools = []
        for pool in pools:
            self._pools.append(pool)

    def _cell_size(self):
        return self._pools[0]["cell_size"]

    def _get_static_size(self, th):
        # For threshold of 16, this works out to be about 12MB on Spectrum-1,
        # and about 17MB on Spectrum-2.
        return th * 8000 * self._cell_size()

    def _get_size(self):
        return self._get_static_size(16)

    def _get_thtype(self):
        return "static"

    def _get_th(self, pool):
        # Threshold value could be any integer between 3 to 16
        th = random.randint(3, 16)
        if pool["thtype"] == "dynamic":
            return th
        else:
            return self._get_static_size(th)

    def _get_pool(self, direction):
        ing_pools = []
        egr_pools = []
        for pool in self._pools:
            if pool["type"] == "ingress":
                ing_pools.append(pool)
            else:
                egr_pools.append(pool)
        if direction == "ingress":
            arr = ing_pools
        else:
            arr = egr_pools
        return arr[random.randint(0, len(arr) - 1)]

    def get_value(self, objid):
        if isinstance(objid, Pool):
            if objid["pool"] in [4, 8, 9, 10]:
                # The threshold type of pools 4, 8, 9 and 10 cannot be changed
                raise SkipTest()
            else:
                return (self._get_size(), self._get_thtype())
        if isinstance(objid, TcBind):
            if objid["tc"] >= 8:
                # Multicast TCs cannot be changed
                raise SkipTest()
            else:
                pool = self._get_pool(objid["type"])
                th = self._get_th(pool)
                pool_n = pool["pool"]
                return (pool_n, th)
        if isinstance(objid, PortPool):
            pool_n = objid["pool"]
            pool = self._pools[pool_n]
            assert pool["pool"] == pool_n
            th = self._get_th(pool)
            return (th,)


class RecordValuePickerException(Exception):
    pass


class RecordValuePicker:
    """
    Class for storing shared buffer configuration. Can handle 2 different
    objects, pool and tcbind. Provide an interface to get the stored values per
    object type.
    """
    def __init__(self, objlist):
        self._recs = []
        for item in objlist:
            self._recs.append({"objid": item, "value": item.var_tuple()})

    def get_value(self, objid):
        if isinstance(objid, Pool) and objid["pool"] in [4, 8, 9, 10]:
            # The threshold type of pools 4, 8, 9 and 10 cannot be changed
            raise SkipTest()
        if isinstance(objid, TcBind) and objid["tc"] >= 8:
            # Multicast TCs cannot be changed
            raise SkipTest()
        for rec in self._recs:
            if rec["objid"].weak_eq(objid):
                return rec["value"]
        raise RecordValuePickerException()


def run_cmd(cmd, json=False):
    out = subprocess.check_output(cmd, shell=True)
    if json:
        return j.loads(out)
    return out


def run_json_cmd(cmd):
    return run_cmd(cmd, json=True)


def log_test(test_name, err_msg=None):
    if err_msg:
        print("\t%s" % err_msg)
        print("TEST: %-80s  [FAIL]" % test_name)
    else:
        print("TEST: %-80s  [ OK ]" % test_name)


class CommonItem(dict):
    varitems = []

    def var_tuple(self):
        ret = []
        self.varitems.sort()
        for key in self.varitems:
            ret.append(self[key])
        return tuple(ret)

    def weak_eq(self, other):
        for key in self:
            if key in self.varitems:
                continue
            if self[key] != other[key]:
                return False
        return True


class CommonList(list):
    def get_by(self, by_obj):
        for item in self:
            if item.weak_eq(by_obj):
                return item
        return None

    def del_by(self, by_obj):
        for item in self:
            if item.weak_eq(by_obj):
                self.remove(item)


class Pool(CommonItem):
    varitems = ["size", "thtype"]

    def dl_set(self, dlname, size, thtype):
        run_cmd("devlink sb pool set {} sb {} pool {} size {} thtype {}".format(dlname, self["sb"],
                                                                                self["pool"],
                                                                                size, thtype))


class PoolList(CommonList):
    pass


def get_pools(dlname, direction=None):
    d = run_json_cmd("devlink sb pool show -j")
    pools = PoolList()
    for pooldict in d["pool"][dlname]:
        if not direction or direction == pooldict["type"]:
            pools.append(Pool(pooldict))
    return pools


def do_check_pools(dlname, pools, vp):
    for pool in pools:
        pre_pools = get_pools(dlname)
        try:
            (size, thtype) = vp.get_value(pool)
        except SkipTest:
            continue
        pool.dl_set(dlname, size, thtype)
        post_pools = get_pools(dlname)
        pool = post_pools.get_by(pool)

        err_msg = None
        if pool["size"] != size:
            err_msg = "Incorrect pool size (got {}, expected {})".format(pool["size"], size)
        if pool["thtype"] != thtype:
            err_msg = "Incorrect pool threshold type (got {}, expected {})".format(pool["thtype"], thtype)

        pre_pools.del_by(pool)
        post_pools.del_by(pool)
        if pre_pools != post_pools:
            err_msg = "Other pool setup changed as well"
        log_test("pool {} of sb {} set verification".format(pool["pool"],
                                                            pool["sb"]), err_msg)


def check_pools(dlname, pools):
    # Save defaults
    record_vp = RecordValuePicker(pools)

    # For each pool, set random size and static threshold type
    do_check_pools(dlname, pools, RandomValuePicker(pools))

    # Restore defaults
    do_check_pools(dlname, pools, record_vp)


class TcBind(CommonItem):
    varitems = ["pool", "threshold"]

    def __init__(self, port, d):
        super(TcBind, self).__init__(d)
        self["dlportname"] = port.name

    def dl_set(self, pool, th):
        run_cmd("devlink sb tc bind set {} sb {} tc {} type {} pool {} th {}".format(self["dlportname"],
                                                                                     self["sb"],
                                                                                     self["tc"],
                                                                                     self["type"],
                                                                                     pool, th))


class TcBindList(CommonList):
    pass


def get_tcbinds(ports, verify_existence=False):
    d = run_json_cmd("devlink sb tc bind show -j -n")
    tcbinds = TcBindList()
    for port in ports:
        err_msg = None
        if port.name not in d["tc_bind"] or len(d["tc_bind"][port.name]) == 0:
            err_msg = "No tc bind for port"
        else:
            for tcbinddict in d["tc_bind"][port.name]:
                tcbinds.append(TcBind(port, tcbinddict))
        if verify_existence:
            log_test("tc bind existence for port {} verification".format(port.name), err_msg)
    return tcbinds


def do_check_tcbind(ports, tcbinds, vp):
    for tcbind in tcbinds:
        pre_tcbinds = get_tcbinds(ports)
        try:
            (pool, th) = vp.get_value(tcbind)
        except SkipTest:
            continue
        tcbind.dl_set(pool, th)
        post_tcbinds = get_tcbinds(ports)
        tcbind = post_tcbinds.get_by(tcbind)

        err_msg = None
        if tcbind["pool"] != pool:
            err_msg = "Incorrect pool (got {}, expected {})".format(tcbind["pool"], pool)
        if tcbind["threshold"] != th:
            err_msg = "Incorrect threshold (got {}, expected {})".format(tcbind["threshold"], th)

        pre_tcbinds.del_by(tcbind)
        post_tcbinds.del_by(tcbind)
        if pre_tcbinds != post_tcbinds:
            err_msg = "Other tc bind setup changed as well"
        log_test("tc bind {}-{} of sb {} set verification".format(tcbind["dlportname"],
                                                                  tcbind["tc"],
                                                                  tcbind["sb"]), err_msg)


def check_tcbind(dlname, ports, pools):
    tcbinds = get_tcbinds(ports, verify_existence=True)

    # Save defaults
    record_vp = RecordValuePicker(tcbinds)

    # Bind each port and unicast TC (TCs < 8) to a random pool and a random
    # threshold
    do_check_tcbind(ports, tcbinds, RandomValuePicker(pools))

    # Restore defaults
    do_check_tcbind(ports, tcbinds, record_vp)


class PortPool(CommonItem):
    varitems = ["threshold"]

    def __init__(self, port, d):
        super(PortPool, self).__init__(d)
        self["dlportname"] = port.name

    def dl_set(self, th):
        run_cmd("devlink sb port pool set {} sb {} pool {} th {}".format(self["dlportname"],
                                                                         self["sb"],
                                                                         self["pool"], th))


class PortPoolList(CommonList):
    pass


def get_portpools(ports, verify_existence=False):
    d = run_json_cmd("devlink sb port pool -j -n")
    portpools = PortPoolList()
    for port in ports:
        err_msg = None
        if port.name not in d["port_pool"] or len(d["port_pool"][port.name]) == 0:
            err_msg = "No port pool for port"
        else:
            for portpooldict in d["port_pool"][port.name]:
                portpools.append(PortPool(port, portpooldict))
        if verify_existence:
            log_test("port pool existence for port {} verification".format(port.name), err_msg)
    return portpools


def do_check_portpool(ports, portpools, vp):
    for portpool in portpools:
        pre_portpools = get_portpools(ports)
        (th,) = vp.get_value(portpool)
        portpool.dl_set(th)
        post_portpools = get_portpools(ports)
        portpool = post_portpools.get_by(portpool)

        err_msg = None
        if portpool["threshold"] != th:
            err_msg = "Incorrect threshold (got {}, expected {})".format(portpool["threshold"], th)

        pre_portpools.del_by(portpool)
        post_portpools.del_by(portpool)
        if pre_portpools != post_portpools:
            err_msg = "Other port pool setup changed as well"
        log_test("port pool {}-{} of sb {} set verification".format(portpool["dlportname"],
                                                                    portpool["pool"],
                                                                    portpool["sb"]), err_msg)


def check_portpool(dlname, ports, pools):
    portpools = get_portpools(ports, verify_existence=True)

    # Save defaults
    record_vp = RecordValuePicker(portpools)

    # For each port pool, set a random threshold
    do_check_portpool(ports, portpools, RandomValuePicker(pools))

    # Restore defaults
    do_check_portpool(ports, portpools, record_vp)


class Port:
    def __init__(self, name):
        self.name = name


class PortList(list):
    pass


def get_ports(dlname):
    d = run_json_cmd("devlink port show -j")
    ports = PortList()
    for name in d["port"]:
        if name.find(dlname) == 0 and d["port"][name]["flavour"] == "physical":
            ports.append(Port(name))
    return ports


def get_device():
    devices_info = run_json_cmd("devlink -j dev info")["info"]
    for d in devices_info:
        if "mlxsw_spectrum" in devices_info[d]["driver"]:
            return d
    return None


class UnavailableDevlinkNameException(Exception):
    pass


def test_sb_configuration():
    # Use static seed
    random.seed(0)

    dlname = get_device()
    if not dlname:
        raise UnavailableDevlinkNameException()

    ports = get_ports(dlname)
    pools = get_pools(dlname)

    check_pools(dlname, pools)
    check_tcbind(dlname, ports, pools)
    check_portpool(dlname, ports, pools)


test_sb_configuration()
