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