"""
  BIER Tables and Routes
"""

import socket
from vpp_object import VppObject
from vpp_ip_route import MPLS_LABEL_INVALID, VppRoutePath, VppMplsLabel


class BIER_HDR_PAYLOAD:
    BIER_HDR_PROTO_MPLS_DOWN_STREAM = 1
    BIER_HDR_PROTO_MPLS_UP_STREAM = 2
    BIER_HDR_PROTO_ETHERNET = 3
    BIER_HDR_PROTO_IPV4 = 4
    BIER_HDR_PROTO_IPV6 = 5
    BIER_HDR_PROTO_VXLAN = 6
    BIER_HDR_PROTO_CTRL = 7
    BIER_HDR_PROTO_OAM = 8


class VppBierTableID:
    def __init__(self, sub_domain_id, set_id, hdr_len_id):
        self.set_id = set_id
        self.sub_domain_id = sub_domain_id
        self.hdr_len_id = hdr_len_id


def find_bier_table(test, bti):
    tables = test.vapi.bier_table_dump()
    for t in tables:
        if (
            bti.set_id == t.bt_tbl_id.bt_set
            and bti.sub_domain_id == t.bt_tbl_id.bt_sub_domain
            and bti.hdr_len_id == t.bt_tbl_id.bt_hdr_len_id
        ):
            return True
    return False


def find_bier_route(test, bti, bp):
    routes = test.vapi.bier_route_dump(bti)
    for r in routes:
        if (
            bti.set_id == r.br_route.br_tbl_id.bt_set
            and bti.sub_domain_id == r.br_route.br_tbl_id.bt_sub_domain
            and bti.hdr_len_id == r.br_route.br_tbl_id.bt_hdr_len_id
            and bp == r.br_route.br_bp
        ):
            return True
    return False


def find_bier_disp_table(test, bdti):
    tables = test.vapi.bier_disp_table_dump()
    for t in tables:
        if bdti == t.bdt_tbl_id:
            return True
    return False


def find_bier_disp_entry(test, bdti, bp):
    entries = test.vapi.bier_disp_entry_dump(bdti)
    for e in entries:
        if bp == e.bde_bp and bdti == e.bde_tbl_id:
            return True
    return False


def find_bier_imp(test, bti, bp):
    imps = test.vapi.bier_imp_dump()
    for i in imps:
        if (
            bti.set_id == i.bi_tbl_id.bt_set
            and bti.sub_domain_id == i.bi_tbl_id.bt_sub_domain
            and bti.hdr_len_id == i.bi_tbl_id.bt_hdr_len_id
            and bp == i.bi_src
        ):
            return True
    return False


class VppBierTable(VppObject):
    """
    BIER Table
    """

    def __init__(self, test, id, mpls_label):
        self._test = test
        self.id = id
        self.mpls_label = mpls_label

    def add_vpp_config(self):
        self._test.vapi.bier_table_add_del(self.id, self.mpls_label, is_add=1)
        self._test.registry.register(self, self._test.logger)

    def remove_vpp_config(self):
        self._test.vapi.bier_table_add_del(self.id, self.mpls_label, is_add=0)

    def object_id(self):
        return "bier-table;[%d:%d:%d]" % (
            self.id.set_id,
            self.id.sub_domain_id,
            self.id.hdr_len_id,
        )

    def query_vpp_config(self):
        return find_bier_table(self._test, self.id)


class VppBierRoute(VppObject):
    """
    BIER route
    """

    def __init__(self, test, tbl_id, bp, paths):
        self._test = test
        self.tbl_id = tbl_id
        self.bp = bp
        self.paths = paths
        self.encoded_paths = []
        for path in self.paths:
            self.encoded_paths.append(path.encode())

    def add_vpp_config(self):
        self._test.vapi.bier_route_add_del(
            self.tbl_id, self.bp, self.encoded_paths, is_add=1
        )
        self._test.registry.register(self, self._test.logger)

    def remove_vpp_config(self):
        self._test.vapi.bier_route_add_del(
            self.tbl_id, self.bp, self.encoded_paths, is_add=0
        )

    def update_paths(self, paths):
        self.paths = paths
        self.encoded_paths = []
        for path in self.paths:
            self.encoded_paths.append(path.encode())
        self._test.vapi.bier_route_add_del(
            self.tbl_id, self.bp, self.encoded_paths, is_replace=1
        )

    def add_path(self, path):
        self.encoded_paths.append(path.encode())
        self._test.vapi.bier_route_add_del(
            self.tbl_id, self.bp, [path.encode()], is_add=1, is_replace=0
        )
        self.paths.append(path)
        self._test.registry.register(self, self._test.logger)

    def remove_path(self, path):
        self.encoded_paths.remove(path.encode())
        self._test.vapi.bier_route_add_del(
            self.tbl_id, self.bp, [path.encode()], is_add=0, is_replace=0
        )
        self.paths.remove(path)

    def remove_all_paths(self):
        self._test.vapi.bier_route_add_del(
            self.tbl_id, self.bp, [], is_add=0, is_replace=1
        )
        self.paths = []

    def object_id(self):
        return "bier-route;[%d:%d:%d:%d]" % (
            self.tbl_id.set_id,
            self.tbl_id.sub_domain_id,
            self.tbl_id.hdr_len_id,
            self.bp,
        )

    def query_vpp_config(self):
        return find_bier_route(self._test, self.tbl_id, self.bp)


class VppBierImp(VppObject):
    """
    BIER route
    """

    def __init__(self, test, tbl_id, src, ibytes):
        self._test = test
        self.tbl_id = tbl_id
        self.ibytes = ibytes
        self.src = src

    def add_vpp_config(self):
        res = self._test.vapi.bier_imp_add(self.tbl_id, self.src, self.ibytes)
        self.bi_index = res.bi_index
        self._test.registry.register(self, self._test.logger)

    def remove_vpp_config(self):
        self._test.vapi.bier_imp_del(self.bi_index)

    def object_id(self):
        return "bier-imp;[%d:%d:%d:%d]" % (
            self.tbl_id.set_id,
            self.tbl_id.sub_domain_id,
            self.tbl_id.hdr_len_id,
            self.src,
        )

    def query_vpp_config(self):
        return find_bier_imp(self._test, self.tbl_id, self.src)


class VppBierDispTable(VppObject):
    """
    BIER Disposition Table
    """

    def __init__(self, test, id):
        self._test = test
        self.id = id

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

    def remove_vpp_config(self):
        self._test.vapi.bier_disp_table_add_del(self.id, is_add=0)

    def object_id(self):
        return "bier-disp-table;[%d]" % (self.id)

    def query_vpp_config(self):
        return find_bier_disp_table(self._test, self.id)


class VppBierDispEntry(VppObject):
    """
    BIER Disposition Entry
    """

    def __init__(
        self, test, tbl_id, bp, payload_proto, nh_proto, nh, nh_tbl, rpf_id=~0
    ):
        self._test = test
        self.tbl_id = tbl_id
        self.nh_tbl = nh_tbl
        self.nh_proto = nh_proto
        self.bp = bp
        self.payload_proto = payload_proto
        self.rpf_id = rpf_id
        self.nh = socket.inet_pton(socket.AF_INET, nh)

    def add_vpp_config(self):
        self._test.vapi.bier_disp_entry_add_del(
            self.tbl_id,
            self.bp,
            self.payload_proto,
            self.nh_proto,
            self.nh,
            self.nh_tbl,
            self.rpf_id,
            is_add=1,
        )
        self._test.registry.register(self, self._test.logger)

    def remove_vpp_config(self):
        self._test.vapi.bier_disp_entry_add_del(
            self.tbl_id,
            self.bp,
            self.payload_proto,
            self.nh_proto,
            self.nh,
            self.nh_tbl,
            self.rpf_id,
            is_add=0,
        )

    def object_id(self):
        return "bier-disp-entry;[%d:%d]" % (self.tbl_id, self.bp)

    def query_vpp_config(self):
        return find_bier_disp_entry(self._test, self.tbl_id, self.bp)
