from ipaddress import IPv4Network

from vpp_object import VppObject
from vpp_papi import VppEnum
from vpp_ip import INVALID_INDEX
from vpp_papi_provider import UnexpectedApiReturnValueError


class VppAclPlugin(VppObject):
    def __init__(self, test, enable_intf_counters=False):
        self._test = test
        self.enable_intf_counters = enable_intf_counters

    @property
    def enable_intf_counters(self):
        return self._enable_intf_counters

    @enable_intf_counters.setter
    def enable_intf_counters(self, enable):
        self.vapi.acl_stats_intf_counters_enable(enable=enable)

    def add_vpp_config(self):
        pass

    def remove_vpp_config(self):
        pass

    def query_vpp_config(self):
        pass

    def object_id(self):
        return "acl-plugin-%d" % (self._sw_if_index)


class AclRule:
    """ACL Rule"""

    # port ranges
    PORTS_ALL = -1
    PORTS_RANGE = 0
    PORTS_RANGE_2 = 1
    udp_sport_from = 10
    udp_sport_to = udp_sport_from + 5
    udp_dport_from = 20000
    udp_dport_to = udp_dport_from + 5000
    tcp_sport_from = 30
    tcp_sport_to = tcp_sport_from + 5
    tcp_dport_from = 40000
    tcp_dport_to = tcp_dport_from + 5000

    udp_sport_from_2 = 90
    udp_sport_to_2 = udp_sport_from_2 + 5
    udp_dport_from_2 = 30000
    udp_dport_to_2 = udp_dport_from_2 + 5000
    tcp_sport_from_2 = 130
    tcp_sport_to_2 = tcp_sport_from_2 + 5
    tcp_dport_from_2 = 20000
    tcp_dport_to_2 = tcp_dport_from_2 + 5000

    icmp4_type = 8  # echo request
    icmp4_code = 3
    icmp6_type = 128  # echo request
    icmp6_code = 3

    icmp4_type_2 = 8
    icmp4_code_from_2 = 5
    icmp4_code_to_2 = 20
    icmp6_type_2 = 128
    icmp6_code_from_2 = 8
    icmp6_code_to_2 = 42

    def __init__(
        self,
        is_permit,
        src_prefix=IPv4Network("0.0.0.0/0"),
        dst_prefix=IPv4Network("0.0.0.0/0"),
        proto=0,
        ports=PORTS_ALL,
        sport_from=None,
        sport_to=None,
        dport_from=None,
        dport_to=None,
    ):
        self.is_permit = is_permit
        self.src_prefix = src_prefix
        self.dst_prefix = dst_prefix
        self._proto = proto
        self._ports = ports
        # assign ports by range
        self.update_ports()
        # assign specified ports
        if sport_from:
            self.sport_from = sport_from
        if sport_to:
            self.sport_to = sport_to
        if dport_from:
            self.dport_from = dport_from
        if dport_to:
            self.dport_to = dport_to

    def __copy__(self):
        new_rule = AclRule(
            self.is_permit,
            self.src_prefix,
            self.dst_prefix,
            self._proto,
            self._ports,
            self.sport_from,
            self.sport_to,
            self.dport_from,
            self.dport_to,
        )
        return new_rule

    def update_ports(self):
        if self._ports == self.PORTS_ALL:
            self.sport_from = 0
            self.dport_from = 0
            self.sport_to = 65535
            if self._proto == 1 or self._proto == 58:
                self.sport_to = 255
            self.dport_to = self.sport_to
        elif self._ports == self.PORTS_RANGE:
            if self._proto == VppEnum.vl_api_ip_proto_t.IP_API_PROTO_ICMP:
                self.sport_from = self.icmp4_type
                self.sport_to = self.icmp4_type
                self.dport_from = self.icmp4_code
                self.dport_to = self.icmp4_code
            elif self._proto == VppEnum.vl_api_ip_proto_t.IP_API_PROTO_ICMP6:
                self.sport_from = self.icmp6_type
                self.sport_to = self.icmp6_type
                self.dport_from = self.icmp6_code
                self.dport_to = self.icmp6_code
            elif self._proto == VppEnum.vl_api_ip_proto_t.IP_API_PROTO_TCP:
                self.sport_from = self.tcp_sport_from
                self.sport_to = self.tcp_sport_to
                self.dport_from = self.tcp_dport_from
                self.dport_to = self.tcp_dport_to
            elif self._proto == VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP:
                self.sport_from = self.udp_sport_from
                self.sport_to = self.udp_sport_to
                self.dport_from = self.udp_dport_from
                self.dport_to = self.udp_dport_to
        elif self._ports == self.PORTS_RANGE_2:
            if self._proto == VppEnum.vl_api_ip_proto_t.IP_API_PROTO_ICMP:
                self.sport_from = self.icmp4_type_2
                self.sport_to = self.icmp4_type_2
                self.dport_from = self.icmp4_code_from_2
                self.dport_to = self.icmp4_code_to_2
            elif self._proto == VppEnum.vl_api_ip_proto_t.IP_API_PROTO_ICMP6:
                self.sport_from = self.icmp6_type_2
                self.sport_to = self.icmp6_type_2
                self.dport_from = self.icmp6_code_from_2
                self.dport_to = self.icmp6_code_to_2
            elif self._proto == VppEnum.vl_api_ip_proto_t.IP_API_PROTO_TCP:
                self.sport_from = self.tcp_sport_from_2
                self.sport_to = self.tcp_sport_to_2
                self.dport_from = self.tcp_dport_from_2
                self.dport_to = self.tcp_dport_to_2
            elif self._proto == VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP:
                self.sport_from = self.udp_sport_from_2
                self.sport_to = self.udp_sport_to_2
                self.dport_from = self.udp_dport_from_2
                self.dport_to = self.udp_dport_to_2
        else:
            self.sport_from = self._ports
            self.sport_to = self._ports
            self.dport_from = self._ports
            self.dport_to = self._ports

    @property
    def proto(self):
        return self._proto

    @proto.setter
    def proto(self, proto):
        self._proto = proto
        self.update_ports()

    @property
    def ports(self):
        return self._ports

    @ports.setter
    def ports(self, ports):
        self._ports = ports
        self.update_ports()

    def encode(self):
        return {
            "is_permit": self.is_permit,
            "proto": self.proto,
            "srcport_or_icmptype_first": self.sport_from,
            "srcport_or_icmptype_last": self.sport_to,
            "src_prefix": self.src_prefix,
            "dstport_or_icmpcode_first": self.dport_from,
            "dstport_or_icmpcode_last": self.dport_to,
            "dst_prefix": self.dst_prefix,
        }


class VppAcl(VppObject):
    """VPP ACL"""

    def __init__(self, test, rules, acl_index=INVALID_INDEX, tag=None):
        self._test = test
        self._acl_index = acl_index
        self.tag = tag
        self._rules = rules

    @property
    def rules(self):
        return self._rules

    @property
    def acl_index(self):
        return self._acl_index

    @property
    def count(self):
        return len(self._rules)

    def encode_rules(self):
        rules = []
        for rule in self._rules:
            rules.append(rule.encode())
        return rules

    def add_vpp_config(self, expect_error=False):
        try:
            reply = self._test.vapi.acl_add_replace(
                acl_index=self._acl_index,
                tag=self.tag,
                count=self.count,
                r=self.encode_rules(),
            )
            self._acl_index = reply.acl_index
            self._test.registry.register(self, self._test.logger)
            if expect_error:
                self._test.fail("Unexpected api reply")
            return self
        except UnexpectedApiReturnValueError:
            if not expect_error:
                self._test.fail("Unexpected api reply")
        return None

    def modify_vpp_config(self, rules):
        self._rules = rules
        self.add_vpp_config()

    def remove_vpp_config(self, expect_error=False):
        try:
            self._test.vapi.acl_del(acl_index=self._acl_index)
            if expect_error:
                self._test.fail("Unexpected api reply")
        except UnexpectedApiReturnValueError:
            if not expect_error:
                self._test.fail("Unexpected api reply")

    def dump(self):
        return self._test.vapi.acl_dump(acl_index=self._acl_index)

    def query_vpp_config(self):
        dump = self.dump()
        for rule in dump:
            if rule.acl_index == self._acl_index:
                return True
        return False

    def object_id(self):
        return "acl-%s-%d" % (self.tag, self._acl_index)


class VppEtypeWhitelist(VppObject):
    """VPP Etype Whitelist"""

    def __init__(self, test, sw_if_index, whitelist, n_input=0):
        self._test = test
        self.whitelist = whitelist
        self.n_input = n_input
        self._sw_if_index = sw_if_index

    @property
    def sw_if_index(self):
        return self._sw_if_index

    @property
    def count(self):
        return len(self.whitelist)

    def add_vpp_config(self):
        self._test.vapi.acl_interface_set_etype_whitelist(
            sw_if_index=self._sw_if_index,
            count=self.count,
            n_input=self.n_input,
            whitelist=self.whitelist,
        )
        self._test.registry.register(self, self._test.logger)
        return self

    def remove_vpp_config(self):
        self._test.vapi.acl_interface_set_etype_whitelist(
            sw_if_index=self._sw_if_index, count=0, n_input=0, whitelist=[]
        )

    def query_vpp_config(self):
        self._test.vapi.acl_interface_etype_whitelist_dump(
            sw_if_index=self._sw_if_index
        )
        return False

    def object_id(self):
        return "acl-etype_wl-%d" % (self._sw_if_index)


class VppAclInterface(VppObject):
    """VPP ACL Interface"""

    def __init__(self, test, sw_if_index, acls, n_input=0):
        self._test = test
        self._sw_if_index = sw_if_index
        self.n_input = n_input
        self.acls = acls

    @property
    def sw_if_index(self):
        return self._sw_if_index

    @property
    def count(self):
        return len(self.acls)

    def encode_acls(self):
        acls = []
        for acl in self.acls:
            acls.append(acl.acl_index)
        return acls

    def add_vpp_config(self, expect_error=False):
        try:
            reply = self._test.vapi.acl_interface_set_acl_list(
                sw_if_index=self._sw_if_index,
                n_input=self.n_input,
                count=self.count,
                acls=self.encode_acls(),
            )
            self._test.registry.register(self, self._test.logger)
            if expect_error:
                self._test.fail("Unexpected api reply")
            return self
        except UnexpectedApiReturnValueError:
            if not expect_error:
                self._test.fail("Unexpected api reply")
        return None

    def remove_vpp_config(self, expect_error=False):
        try:
            reply = self._test.vapi.acl_interface_set_acl_list(
                sw_if_index=self._sw_if_index, n_input=0, count=0, acls=[]
            )
            if expect_error:
                self._test.fail("Unexpected api reply")
        except UnexpectedApiReturnValueError:
            if not expect_error:
                self._test.fail("Unexpected api reply")

    def query_vpp_config(self):
        dump = self._test.vapi.acl_interface_list_dump(sw_if_index=self._sw_if_index)
        for acl_list in dump:
            if acl_list.count > 0:
                return True
        return False

    def object_id(self):
        return "acl-if-list-%d" % (self._sw_if_index)


class MacipRule:
    """Mac Ip rule"""

    def __init__(
        self, is_permit, src_mac=0, src_mac_mask=0, src_prefix=IPv4Network("0.0.0.0/0")
    ):
        self.is_permit = is_permit
        self.src_mac = src_mac
        self.src_mac_mask = src_mac_mask
        self.src_prefix = src_prefix

    def encode(self):
        return {
            "is_permit": self.is_permit,
            "src_mac": self.src_mac,
            "src_mac_mask": self.src_mac_mask,
            "src_prefix": self.src_prefix,
        }


class VppMacipAcl(VppObject):
    """Vpp Mac Ip ACL"""

    def __init__(self, test, rules, acl_index=INVALID_INDEX, tag=None):
        self._test = test
        self._acl_index = acl_index
        self.tag = tag
        self._rules = rules

    @property
    def acl_index(self):
        return self._acl_index

    @property
    def rules(self):
        return self._rules

    @property
    def count(self):
        return len(self._rules)

    def encode_rules(self):
        rules = []
        for rule in self._rules:
            rules.append(rule.encode())
        return rules

    def add_vpp_config(self, expect_error=False):
        try:
            reply = self._test.vapi.macip_acl_add_replace(
                acl_index=self._acl_index,
                tag=self.tag,
                count=self.count,
                r=self.encode_rules(),
            )
            self._acl_index = reply.acl_index
            self._test.registry.register(self, self._test.logger)
            if expect_error:
                self._test.fail("Unexpected api reply")
            return self
        except UnexpectedApiReturnValueError:
            if not expect_error:
                self._test.fail("Unexpected api reply")
        return None

    def modify_vpp_config(self, rules):
        self._rules = rules
        self.add_vpp_config()

    def remove_vpp_config(self, expect_error=False):
        try:
            self._test.vapi.macip_acl_del(acl_index=self._acl_index)
            if expect_error:
                self._test.fail("Unexpected api reply")
        except UnexpectedApiReturnValueError:
            if not expect_error:
                self._test.fail("Unexpected api reply")

    def dump(self):
        return self._test.vapi.macip_acl_dump(acl_index=self._acl_index)

    def query_vpp_config(self):
        dump = self.dump()
        for rule in dump:
            if rule.acl_index == self._acl_index:
                return True
        return False

    def object_id(self):
        return "macip-acl-%s-%d" % (self.tag, self._acl_index)


class VppMacipAclInterface(VppObject):
    """VPP Mac Ip ACL Interface"""

    def __init__(self, test, sw_if_index, acls):
        self._test = test
        self._sw_if_index = sw_if_index
        self.acls = acls

    @property
    def sw_if_index(self):
        return self._sw_if_index

    @property
    def count(self):
        return len(self.acls)

    def add_vpp_config(self):
        for acl in self.acls:
            self._test.vapi.macip_acl_interface_add_del(
                is_add=True, sw_if_index=self._sw_if_index, acl_index=acl.acl_index
            )
        self._test.registry.register(self, self._test.logger)

    def remove_vpp_config(self):
        for acl in self.acls:
            self._test.vapi.macip_acl_interface_add_del(
                is_add=False, sw_if_index=self._sw_if_index, acl_index=acl.acl_index
            )

    def dump(self):
        return self._test.vapi.macip_acl_interface_list_dump(
            sw_if_index=self._sw_if_index
        )

    def query_vpp_config(self):
        dump = self.dump()
        for acl_list in dump:
            for acl_index in acl_list.acls:
                if acl_index != INVALID_INDEX:
                    return True
        return False

    def object_id(self):
        return "macip-acl-if-list-%d" % (self._sw_if_index)
