"""
  IP Routes

  object abstractions for representing IP routes in VPP
"""

from vpp_object import VppObject
from vpp_ip import DpoProto, INVALID_INDEX, VppIpAddressUnion, VppIpMPrefix
from ipaddress import ip_network, ip_address, IPv4Network, IPv6Network
from vpp_papi_exceptions import UnexpectedApiReturnValueError

# from vnet/vnet/mpls/mpls_types.h
MPLS_IETF_MAX_LABEL = 0xFFFFF
MPLS_LABEL_INVALID = MPLS_IETF_MAX_LABEL + 1

try:
    text_type = unicode
except NameError:
    text_type = str


class FibPathProto:
    FIB_PATH_NH_PROTO_IP4 = 0
    FIB_PATH_NH_PROTO_IP6 = 1
    FIB_PATH_NH_PROTO_MPLS = 2
    FIB_PATH_NH_PROTO_ETHERNET = 3
    FIB_PATH_NH_PROTO_BIER = 4
    FIB_PATH_NH_PROTO_NSH = 5


class FibPathType:
    FIB_PATH_TYPE_NORMAL = 0
    FIB_PATH_TYPE_LOCAL = 1
    FIB_PATH_TYPE_DROP = 2
    FIB_PATH_TYPE_UDP_ENCAP = 3
    FIB_PATH_TYPE_BIER_IMP = 4
    FIB_PATH_TYPE_ICMP_UNREACH = 5
    FIB_PATH_TYPE_ICMP_PROHIBIT = 6
    FIB_PATH_TYPE_SOURCE_LOOKUP = 7
    FIB_PATH_TYPE_DVR = 8
    FIB_PATH_TYPE_INTERFACE_RX = 9
    FIB_PATH_TYPE_CLASSIFY = 10


class FibPathFlags:
    FIB_PATH_FLAG_NONE = 0
    FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED = 1
    FIB_PATH_FLAG_RESOLVE_VIA_HOST = 2
    FIB_PATH_FLAG_POP_PW_CW = 4


class MplsLspMode:
    PIPE = 0
    UNIFORM = 1


def mk_network(addr, len):
    if ip_address(text_type(addr)).version == 4:
        return IPv4Network("%s/%d" % (addr, len), strict=False)
    else:
        return IPv6Network("%s/%d" % (addr, len), strict=False)


def ip_to_dpo_proto(addr):
    if addr.version == 6:
        return DpoProto.DPO_PROTO_IP6
    else:
        return DpoProto.DPO_PROTO_IP4


def address_proto(ip_addr):
    if ip_addr.ip_addr.version == 4:
        return FibPathProto.FIB_PATH_NH_PROTO_IP4
    else:
        return FibPathProto.FIB_PATH_NH_PROTO_IP6


def find_route(
    test, addr, len, table_id=0, sw_if_index=None, ignore_default_route=False
):
    prefix = mk_network(addr, len)

    if 4 == prefix.version:
        routes = test.vapi.ip_route_dump(table_id, False)
    else:
        routes = test.vapi.ip_route_dump(table_id, True)

    for e in routes:
        if table_id == e.route.table_id and str(e.route.prefix) == str(prefix):
            if not sw_if_index:
                # if the route is a default one of the table:
                # 0.0.0.0/0, 0.0.0.0/32, 240.0.0.0/4, 255.255.255.255/32
                return not (
                    ignore_default_route
                    and e.route.n_paths == 1
                    and e.route.paths[0].type == FibPathType.FIB_PATH_TYPE_DROP
                )
            else:
                # should be only one path if the user is looking
                # for the interface the route is reachable through
                if e.route.n_paths != 1:
                    return False
                else:
                    return e.route.paths[0].sw_if_index == sw_if_index

    return False


def find_route_in_dump(dump, route, table):
    for r in dump:
        if table.table_id == r.route.table_id and route.prefix == r.route.prefix:
            if len(route.paths) == r.route.n_paths:
                return True
    return False


def find_mroute_in_dump(dump, route, table):
    for r in dump:
        if table.table_id == r.route.table_id and route.prefix == r.route.prefix:
            return True
    return False


def find_mroute(test, grp_addr, src_addr, grp_addr_len, table_id=0):
    ip_mprefix = VppIpMPrefix(text_type(src_addr), text_type(grp_addr), grp_addr_len)

    if 4 == ip_mprefix.version:
        routes = test.vapi.ip_mroute_dump(table_id, False)
    else:
        routes = test.vapi.ip_mroute_dump(table_id, True)

    for e in routes:
        if table_id == e.route.table_id and ip_mprefix == e.route.prefix:
            return True
    return False


def find_mpls_route(test, table_id, label, eos_bit, paths=None):
    dump = test.vapi.mpls_route_dump(table_id)
    for e in dump:
        if (
            label == e.mr_route.mr_label
            and eos_bit == e.mr_route.mr_eos
            and table_id == e.mr_route.mr_table_id
        ):
            if not paths:
                return True
            else:
                if len(paths) != len(e.mr_route.mr_paths):
                    return False
                for i in range(len(paths)):
                    if paths[i] != e.mr_route.mr_paths[i]:
                        return False
                return True
    return False


def fib_interface_ip_prefix(test, addr, len, sw_if_index):
    # can't use python net here since we need the host bits in the prefix
    prefix = "%s/%d" % (addr, len)
    addrs = test.vapi.ip_address_dump(
        sw_if_index, is_ipv6=(6 == ip_address(addr).version)
    )

    for a in addrs:
        if a.sw_if_index == sw_if_index and str(a.prefix) == prefix:
            return True
    return False


class VppIpTable(VppObject):
    def __init__(
        self, test, table_id, is_ip6=0, register=True, name="", create_mfib=True
    ):
        self._test = test
        self.name = name
        self.table_id = table_id
        self.is_ip6 = is_ip6
        self.register = register
        self.create_mfib = True

    def add_vpp_config(self):
        self._test.vapi.ip_table_add_del_v2(
            is_add=1,
            create_mfib=self.create_mfib,
            table={"is_ip6": self.is_ip6, "table_id": self.table_id, "name": self.name},
        )
        if self.register:
            self._test.registry.register(self, self._test.logger)
        return self

    def remove_vpp_config(self):
        self._test.vapi.ip_table_add_del_v2(
            is_add=0, table={"is_ip6": self.is_ip6, "table_id": self.table_id}
        )

    def replace_begin(self):
        self._test.vapi.ip_table_replace_begin(
            table={"is_ip6": self.is_ip6, "table_id": self.table_id}
        )

    def replace_end(self):
        self._test.vapi.ip_table_replace_end(
            table={"is_ip6": self.is_ip6, "table_id": self.table_id}
        )

    def flush(self):
        self._test.vapi.ip_table_flush(
            table={"is_ip6": self.is_ip6, "table_id": self.table_id}
        )

    def dump(self):
        return self._test.vapi.ip_route_dump(self.table_id, self.is_ip6)

    def mdump(self):
        return self._test.vapi.ip_mroute_dump(self.table_id, self.is_ip6)

    def query_vpp_config(self):
        if self.table_id == 0:
            # the default table always exists
            return False
        # find the default route
        return find_route(
            self._test, "::" if self.is_ip6 else "0.0.0.0", 0, self.table_id
        )

    def object_id(self):
        return "table-%s-%d" % ("v6" if self.is_ip6 == 1 else "v4", self.table_id)


class VppIpInterfaceAddress(VppObject):
    def __init__(self, test, intf, addr, len, bind=None):
        self._test = test
        self.intf = intf
        self.addr = addr
        self.len = len
        self.prefix = "%s/%d" % (addr, len)
        self.host_len = ip_network(self.prefix, strict=False).max_prefixlen
        self.table_id = 0
        if bind:
            self.table_id = bind.table.table_id

    def add_vpp_config(self):
        self._test.vapi.sw_interface_add_del_address(
            sw_if_index=self.intf.sw_if_index, prefix=self.prefix, is_add=1
        )
        self._test.registry.register(self, self._test.logger)
        return self

    def remove_vpp_config(self):
        self._test.vapi.sw_interface_add_del_address(
            sw_if_index=self.intf.sw_if_index, prefix=self.prefix, is_add=0
        )

    def query_vpp_config(self):
        # search for the IP address mapping and the two expected
        # FIB entries
        v = ip_address(self.addr).version

        if (v == 4 and self.len < 31) or (v == 6 and self.len < 127):
            return (
                fib_interface_ip_prefix(
                    self._test, self.addr, self.len, self.intf.sw_if_index
                )
                & find_route(
                    self._test,
                    self.addr,
                    self.len,
                    table_id=self.table_id,
                    sw_if_index=self.intf.sw_if_index,
                )
                & find_route(
                    self._test,
                    self.addr,
                    self.host_len,
                    table_id=self.table_id,
                    sw_if_index=self.intf.sw_if_index,
                )
            )
        else:
            return fib_interface_ip_prefix(
                self._test, self.addr, self.len, self.intf.sw_if_index
            ) & find_route(
                self._test,
                self.addr,
                self.host_len,
                table_id=self.table_id,
                sw_if_index=self.intf.sw_if_index,
            )

    def object_id(self):
        return "interface-ip-%s-%d-%s" % (self.intf, self.table_id, self.prefix)


class VppIp6LinkLocalAddress(VppObject):
    def __init__(self, test, intf, addr):
        self._test = test
        self.intf = intf
        self.addr = addr

    def add_vpp_config(self):
        self._test.vapi.sw_interface_ip6_set_link_local_address(
            sw_if_index=self.intf.sw_if_index, ip=self.addr
        )
        self._test.registry.register(self, self._test.logger)
        return self

    def remove_vpp_config(self):
        # link locals can't be removed, only changed
        pass

    def query_vpp_config(self):
        # no API to query
        return False

    def object_id(self):
        return "ip6-link-local-%s-%s" % (self.intf, self.addr)


class VppIpInterfaceBind(VppObject):
    def __init__(self, test, intf, table):
        self._test = test
        self.intf = intf
        self.table = table

    def add_vpp_config(self):
        if self.table.is_ip6:
            self.intf.set_table_ip6(self.table.table_id)
        else:
            self.intf.set_table_ip4(self.table.table_id)
        self._test.registry.register(self, self._test.logger)
        return self

    def remove_vpp_config(self):
        if 0 == self.table.table_id:
            return
        if self.table.is_ip6:
            self.intf.set_table_ip6(0)
        else:
            self.intf.set_table_ip4(0)

    def query_vpp_config(self):
        if 0 == self.table.table_id:
            return False
        try:
            return (
                self._test.vapi.sw_interface_get_table(
                    self.intf.sw_if_index, self.table.is_ip6
                ).vrf_id
                == self.table.table_id
            )
        except UnexpectedApiReturnValueError as e:
            if e.retval == -2:  # INVALID_SW_IF_INDEX
                return False
            raise

    def object_id(self):
        return "interface-bind-%s-%s" % (self.intf, self.table)


class VppMplsLabel:
    def __init__(self, value, mode=MplsLspMode.PIPE, ttl=64, exp=0):
        self.value = value
        self.mode = mode
        self.ttl = ttl
        self.exp = exp

    def encode(self):
        is_uniform = 0 if self.mode is MplsLspMode.PIPE else 1
        return {
            "label": self.value,
            "ttl": self.ttl,
            "exp": self.exp,
            "is_uniform": is_uniform,
        }

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return (
                self.value == other.value
                and self.ttl == other.ttl
                and self.exp == other.exp
                and self.mode == other.mode
            )
        elif hasattr(other, "label"):
            return (
                self.value == other.label
                and self.ttl == other.ttl
                and self.exp == other.exp
                and (self.mode == MplsLspMode.UNIFORM) == other.is_uniform
            )
        else:
            return False

    def __ne__(self, other):
        return not (self == other)


class VppFibPathNextHop:
    def __init__(self, addr, via_label=MPLS_LABEL_INVALID, next_hop_id=INVALID_INDEX):
        self.addr = VppIpAddressUnion(addr)
        self.via_label = via_label
        self.obj_id = next_hop_id

    def encode(self):
        if self.via_label is not MPLS_LABEL_INVALID:
            return {"via_label": self.via_label}
        if self.obj_id is not INVALID_INDEX:
            return {"obj_id": self.obj_id}
        else:
            return {"address": self.addr.encode()}

    def proto(self):
        if self.via_label is MPLS_LABEL_INVALID:
            return address_proto(self.addr)
        else:
            return FibPathProto.FIB_PATH_NH_PROTO_MPLS

    def __eq__(self, other):
        if not isinstance(other, self.__class__):
            # try the other instance's __eq__.
            return NotImplemented
        return (
            self.addr == other.addr
            and self.via_label == other.via_label
            and self.obj_id == other.obj_id
        )


class VppRoutePath:
    def __init__(
        self,
        nh_addr,
        nh_sw_if_index,
        nh_table_id=0,
        labels=[],
        nh_via_label=MPLS_LABEL_INVALID,
        rpf_id=0,
        next_hop_id=INVALID_INDEX,
        proto=None,
        flags=FibPathFlags.FIB_PATH_FLAG_NONE,
        type=FibPathType.FIB_PATH_TYPE_NORMAL,
    ):
        self.nh_itf = nh_sw_if_index
        self.nh_table_id = nh_table_id
        self.nh_labels = labels
        self.weight = 1
        self.rpf_id = rpf_id
        self.proto = proto
        self.flags = flags
        self.type = type
        self.nh = VppFibPathNextHop(nh_addr, nh_via_label, next_hop_id)
        if proto is None:
            self.proto = self.nh.proto()
        else:
            self.proto = proto
        self.next_hop_id = next_hop_id

    def encode_labels(self):
        lstack = []
        for l in self.nh_labels:
            if type(l) == VppMplsLabel:
                lstack.append(l.encode())
            else:
                lstack.append({"label": l, "ttl": 255})
        while len(lstack) < 16:
            lstack.append({})

        return lstack

    def encode(self):
        return {
            "weight": 1,
            "preference": 0,
            "table_id": self.nh_table_id,
            "nh": self.nh.encode(),
            "next_hop_id": self.next_hop_id,
            "sw_if_index": self.nh_itf,
            "rpf_id": self.rpf_id,
            "proto": self.proto,
            "type": self.type,
            "flags": self.flags,
            "n_labels": len(self.nh_labels),
            "label_stack": self.encode_labels(),
        }

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return self.nh == other.nh
        elif hasattr(other, "sw_if_index"):
            # vl_api_fib_path_t
            if len(self.nh_labels) != other.n_labels:
                return False
            for i in range(len(self.nh_labels)):
                if self.nh_labels[i] != other.label_stack[i]:
                    return False
            return self.nh_itf == other.sw_if_index
        else:
            return False

    def __ne__(self, other):
        return not (self == other)


class VppMRoutePath(VppRoutePath):
    def __init__(
        self,
        nh_sw_if_index,
        flags,
        nh=None,
        proto=FibPathProto.FIB_PATH_NH_PROTO_IP4,
        type=FibPathType.FIB_PATH_TYPE_NORMAL,
        bier_imp=INVALID_INDEX,
    ):
        if not nh:
            nh = "::" if proto is FibPathProto.FIB_PATH_NH_PROTO_IP6 else "0.0.0.0"
        super(VppMRoutePath, self).__init__(
            nh, nh_sw_if_index, proto=proto, type=type, next_hop_id=bier_imp
        )
        self.nh_i_flags = flags
        self.bier_imp = bier_imp

    def encode(self):
        return {
            "path": super(VppMRoutePath, self).encode(),
            "itf_flags": self.nh_i_flags,
        }


class VppIpRoute(VppObject):
    """
    IP Route
    """

    def __init__(
        self, test, dest_addr, dest_addr_len, paths, table_id=0, register=True
    ):
        self._test = test
        self.paths = paths
        self.table_id = table_id
        self.prefix = mk_network(dest_addr, dest_addr_len)
        self.register = register
        self.stats_index = None
        self.modified = False

        self.encoded_paths = []
        for path in self.paths:
            self.encoded_paths.append(path.encode())

    def __eq__(self, other):
        if self.table_id == other.table_id and self.prefix == other.prefix:
            return True
        return False

    def modify(self, paths):
        self.paths = paths
        self.encoded_paths = []
        for path in self.paths:
            self.encoded_paths.append(path.encode())
        self.modified = True

        self._test.vapi.ip_route_add_del(
            route={
                "table_id": self.table_id,
                "prefix": self.prefix,
                "n_paths": len(self.encoded_paths),
                "paths": self.encoded_paths,
            },
            is_add=1,
            is_multipath=0,
        )

    def add_vpp_config(self):
        r = self._test.vapi.ip_route_add_del(
            route={
                "table_id": self.table_id,
                "prefix": self.prefix,
                "n_paths": len(self.encoded_paths),
                "paths": self.encoded_paths,
            },
            is_add=1,
            is_multipath=0,
        )
        self.stats_index = r.stats_index
        if self.register:
            self._test.registry.register(self, self._test.logger)
        return self

    def remove_vpp_config(self):
        # there's no need to issue different deletes for modified routes
        # we do this only to test the two different ways to delete routes
        # eiter by passing all the paths to remove and mutlipath=1 or
        # passing no paths and multipath=0
        if self.modified:
            self._test.vapi.ip_route_add_del(
                route={
                    "table_id": self.table_id,
                    "prefix": self.prefix,
                    "n_paths": len(self.encoded_paths),
                    "paths": self.encoded_paths,
                },
                is_add=0,
                is_multipath=1,
            )
        else:
            self._test.vapi.ip_route_add_del(
                route={"table_id": self.table_id, "prefix": self.prefix, "n_paths": 0},
                is_add=0,
                is_multipath=0,
            )

    def query_vpp_config(self):
        return find_route(
            self._test,
            self.prefix.network_address,
            self.prefix.prefixlen,
            self.table_id,
            ignore_default_route=True,
        )

    def object_id(self):
        return "%s:table-%d-%s" % (
            "ip6-route" if self.prefix.version == 6 else "ip-route",
            self.table_id,
            self.prefix,
        )

    def get_stats_to(self):
        c = self._test.statistics.get_counter("/net/route/to")
        return c[0][self.stats_index]

    def get_stats_via(self):
        c = self._test.statistics.get_counter("/net/route/via")
        return c[0][self.stats_index]


class VppIpRouteV2(VppObject):
    """
    IP Route V2
    """

    def __init__(
        self, test, dest_addr, dest_addr_len, paths, table_id=0, register=True, src=0
    ):
        self._test = test
        self.paths = paths
        self.table_id = table_id
        self.prefix = mk_network(dest_addr, dest_addr_len)
        self.register = register
        self.stats_index = None
        self.modified = False
        self.src = src

        self.encoded_paths = []
        for path in self.paths:
            self.encoded_paths.append(path.encode())

    def __eq__(self, other):
        if self.table_id == other.table_id and self.prefix == other.prefix:
            return True
        return False

    def modify(self, paths):
        self.paths = paths
        self.encoded_paths = []
        for path in self.paths:
            self.encoded_paths.append(path.encode())
        self.modified = True

        self._test.vapi.ip_route_add_del_v2(
            route={
                "table_id": self.table_id,
                "prefix": self.prefix,
                "src": self.src,
                "n_paths": len(self.encoded_paths),
                "paths": self.encoded_paths,
            },
            is_add=1,
            is_multipath=0,
        )

    def add_vpp_config(self):
        r = self._test.vapi.ip_route_add_del_v2(
            route={
                "table_id": self.table_id,
                "prefix": self.prefix,
                "n_paths": len(self.encoded_paths),
                "paths": self.encoded_paths,
                "src": self.src,
            },
            is_add=1,
            is_multipath=0,
        )
        self.stats_index = r.stats_index
        if self.register:
            self._test.registry.register(self, self._test.logger)
        return self

    def remove_vpp_config(self):
        # there's no need to issue different deletes for modified routes
        # we do this only to test the two different ways to delete routes
        # eiter by passing all the paths to remove and mutlipath=1 or
        # passing no paths and multipath=0
        if self.modified:
            self._test.vapi.ip_route_add_del_v2(
                route={
                    "table_id": self.table_id,
                    "prefix": self.prefix,
                    "src": self.src,
                    "n_paths": len(self.encoded_paths),
                    "paths": self.encoded_paths,
                },
                is_add=0,
                is_multipath=1,
            )
        else:
            self._test.vapi.ip_route_add_del_v2(
                route={
                    "table_id": self.table_id,
                    "prefix": self.prefix,
                    "src": self.src,
                    "n_paths": 0,
                },
                is_add=0,
                is_multipath=0,
            )

    def query_vpp_config(self):
        return find_route(
            self._test,
            self.prefix.network_address,
            self.prefix.prefixlen,
            self.table_id,
            ignore_default_route=True,
        )

    def object_id(self):
        return "%s:table-%d-%s" % (
            "ip6-route" if self.prefix.version == 6 else "ip-route",
            self.table_id,
            self.prefix,
        )

    def get_stats_to(self):
        c = self._test.statistics.get_counter("/net/route/to")
        return c[0][self.stats_index]

    def get_stats_via(self):
        c = self._test.statistics.get_counter("/net/route/via")
        return c[0][self.stats_index]


class VppIpMRoute(VppObject):
    """
    IP Multicast Route
    """

    def __init__(
        self,
        test,
        src_addr,
        grp_addr,
        grp_addr_len,
        e_flags,
        paths,
        table_id=0,
        rpf_id=0,
    ):
        self._test = test
        self.paths = paths
        self.table_id = table_id
        self.e_flags = e_flags
        self.rpf_id = rpf_id

        self.prefix = VppIpMPrefix(src_addr, grp_addr, grp_addr_len)
        self.encoded_paths = []
        for path in self.paths:
            self.encoded_paths.append(path.encode())

    def encode(self, paths=None):
        _paths = self.encoded_paths if paths is None else paths
        return {
            "table_id": self.table_id,
            "entry_flags": self.e_flags,
            "rpf_id": self.rpf_id,
            "prefix": self.prefix.encode(),
            "n_paths": len(_paths),
            "paths": _paths,
        }

    def add_vpp_config(self):
        r = self._test.vapi.ip_mroute_add_del(
            route=self.encode(), is_multipath=1, is_add=1
        )
        self.stats_index = r.stats_index
        self._test.registry.register(self, self._test.logger)
        return self

    def remove_vpp_config(self):
        self._test.vapi.ip_mroute_add_del(route=self.encode(), is_multipath=1, is_add=0)

    def update_entry_flags(self, flags):
        self.e_flags = flags
        self._test.vapi.ip_mroute_add_del(
            route=self.encode(paths=[]), is_multipath=1, is_add=1
        )

    def update_rpf_id(self, rpf_id):
        self.rpf_id = rpf_id
        self._test.vapi.ip_mroute_add_del(
            route=self.encode(paths=[]), is_multipath=1, is_add=1
        )

    def update_path_flags(self, itf, flags):
        for p in range(len(self.paths)):
            if self.paths[p].nh_itf == itf:
                self.paths[p].nh_i_flags = flags
                self.encoded_paths[p] = self.paths[p].encode()
                break

        self._test.vapi.ip_mroute_add_del(
            route=self.encode(paths=[self.encoded_paths[p]]), is_add=1, is_multipath=0
        )

    def query_vpp_config(self):
        return find_mroute(
            self._test,
            self.prefix.gaddr,
            self.prefix.saddr,
            self.prefix.length,
            self.table_id,
        )

    def object_id(self):
        return "%d:(%s,%s/%d)" % (
            self.table_id,
            self.prefix.saddr,
            self.prefix.gaddr,
            self.prefix.length,
        )

    def get_stats(self):
        c = self._test.statistics.get_counter("/net/mroute")
        return c[0][self.stats_index]


class VppMFibSignal:
    def __init__(self, test, route, interface, packet):
        self.route = route
        self.interface = interface
        self.packet = packet
        self.test = test

    def compare(self, signal):
        self.test.assertEqual(self.interface, signal.sw_if_index)
        self.test.assertEqual(self.route.table_id, signal.table_id)
        self.test.assertEqual(self.route.prefix, signal.prefix)


class VppMplsIpBind(VppObject):
    """
    MPLS to IP Binding
    """

    def __init__(
        self,
        test,
        local_label,
        dest_addr,
        dest_addr_len,
        table_id=0,
        ip_table_id=0,
        is_ip6=0,
    ):
        self._test = test
        self.dest_addr_len = dest_addr_len
        self.dest_addr = dest_addr
        self.ip_addr = ip_address(text_type(dest_addr))
        self.local_label = local_label
        self.table_id = table_id
        self.ip_table_id = ip_table_id
        self.prefix = mk_network(dest_addr, dest_addr_len)

    def add_vpp_config(self):
        self._test.vapi.mpls_ip_bind_unbind(
            self.local_label,
            self.prefix,
            table_id=self.table_id,
            ip_table_id=self.ip_table_id,
        )
        self._test.registry.register(self, self._test.logger)

    def remove_vpp_config(self):
        self._test.vapi.mpls_ip_bind_unbind(
            self.local_label,
            self.prefix,
            table_id=self.table_id,
            ip_table_id=self.ip_table_id,
            is_bind=0,
        )

    def query_vpp_config(self):
        dump = self._test.vapi.mpls_route_dump(self.table_id)
        for e in dump:
            if (
                self.local_label == e.mr_route.mr_label
                and self.table_id == e.mr_route.mr_table_id
            ):
                return True
        return False

    def object_id(self):
        return "%d:%s binds %d:%s/%d" % (
            self.table_id,
            self.local_label,
            self.ip_table_id,
            self.dest_addr,
            self.dest_addr_len,
        )


class VppMplsTable(VppObject):
    def __init__(self, test, table_id):
        self._test = test
        self.table_id = table_id

    def add_vpp_config(self):
        self._test.vapi.mpls_table_add_del(self.table_id, is_add=1)
        self._test.registry.register(self, self._test.logger)

    def remove_vpp_config(self):
        self._test.vapi.mpls_table_add_del(self.table_id, is_add=0)

    def query_vpp_config(self):
        dump = self._test.vapi.mpls_table_dump()
        for d in dump:
            if d.mt_table.mt_table_id == self.table_id:
                return True
        return False

    def object_id(self):
        return "table-mpls-%d" % (self.table_id)


class VppMplsRoute(VppObject):
    """
    MPLS Route/LSP
    """

    def __init__(
        self,
        test,
        local_label,
        eos_bit,
        paths,
        table_id=0,
        is_multicast=0,
        eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP4,
    ):
        self._test = test
        self.paths = paths
        self.local_label = local_label
        self.eos_bit = eos_bit
        self.eos_proto = eos_proto
        self.table_id = table_id
        self.is_multicast = is_multicast

    def add_vpp_config(self):
        paths = []
        for path in self.paths:
            paths.append(path.encode())

        r = self._test.vapi.mpls_route_add_del(
            self.table_id,
            self.local_label,
            self.eos_bit,
            self.eos_proto,
            self.is_multicast,
            paths,
            1,
            0,
        )
        self.stats_index = r.stats_index
        self._test.registry.register(self, self._test.logger)

    def remove_vpp_config(self):
        paths = []
        for path in self.paths:
            paths.append(path.encode())

        self._test.vapi.mpls_route_add_del(
            self.table_id,
            self.local_label,
            self.eos_bit,
            self.eos_proto,
            self.is_multicast,
            paths,
            0,
            0,
        )

    def query_vpp_config(self):
        return find_mpls_route(
            self._test, self.table_id, self.local_label, self.eos_bit
        )

    def object_id(self):
        return "mpls-route-%d:%s/%d" % (
            self.table_id,
            self.local_label,
            20 + self.eos_bit,
        )

    def get_stats_to(self):
        c = self._test.statistics.get_counter("/net/route/to")
        return c[0][self.stats_index]

    def get_stats_via(self):
        c = self._test.statistics.get_counter("/net/route/via")
        return c[0][self.stats_index]
