from vpp_object import VppObject
from ipaddress import ip_address
from vpp_papi import VppEnum
from vpp_interface import VppInterface

try:
    text_type = unicode
except NameError:
    text_type = str


def mk_counter():
    return {"packets": 0, "bytes": 0}


class VppIpsecSpd(VppObject):
    """
    VPP SPD DB
    """

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

    def add_vpp_config(self):
        self.test.vapi.ipsec_spd_add_del(self.id)
        self.test.registry.register(self, self.test.logger)

    def remove_vpp_config(self):
        self.test.vapi.ipsec_spd_add_del(self.id, is_add=0)

    def object_id(self):
        return "ipsec-spd-%d" % self.id

    def query_vpp_config(self):
        spds = self.test.vapi.ipsec_spds_dump()
        for spd in spds:
            if spd.spd_id == self.id:
                return True
        return False


class VppIpsecSpdItfBinding(VppObject):
    """
    VPP SPD DB to interface binding
    (i.e. this SPD is used on this interface)
    """

    def __init__(self, test, spd, itf):
        self.test = test
        self.spd = spd
        self.itf = itf

    def add_vpp_config(self):
        self.test.vapi.ipsec_interface_add_del_spd(self.spd.id, self.itf.sw_if_index)
        self.test.registry.register(self, self.test.logger)

    def remove_vpp_config(self):
        self.test.vapi.ipsec_interface_add_del_spd(
            self.spd.id, self.itf.sw_if_index, is_add=0
        )

    def object_id(self):
        return "bind-%s-to-%s" % (self.spd.id, self.itf)

    def query_vpp_config(self):
        bs = self.test.vapi.ipsec_spd_interface_dump()
        for b in bs:
            if b.sw_if_index == self.itf.sw_if_index:
                return True
        return False


class VppIpsecSpdEntry(VppObject):
    """
    VPP SPD DB Entry
    """

    def __init__(
        self,
        test,
        spd,
        sa_id,
        local_start,
        local_stop,
        remote_start,
        remote_stop,
        proto=socket.IPPROTO_RAW,
        priority=100,
        policy=None,
        is_outbound=1,
        remote_port_start=0,
        remote_port_stop=65535,
        local_port_start=0,
        local_port_stop=65535,
    ):
        self.test = test
        self.spd = spd
        self.sa_id = sa_id
        self.local_start = ip_address(text_type(local_start))
        self.local_stop = ip_address(text_type(local_stop))
        self.remote_start = ip_address(text_type(remote_start))
        self.remote_stop = ip_address(text_type(remote_stop))
        self.proto = proto
        self.is_outbound = is_outbound
        self.priority = priority
        if not policy:
            self.policy = VppEnum.vl_api_ipsec_spd_action_t.IPSEC_API_SPD_ACTION_BYPASS
        else:
            self.policy = policy
        self.is_ipv6 = 0 if self.local_start.version == 4 else 1
        self.local_port_start = local_port_start
        self.local_port_stop = local_port_stop
        self.remote_port_start = remote_port_start
        self.remote_port_stop = remote_port_stop

    def add_vpp_config(self):
        rv = self.test.vapi.ipsec_spd_entry_add_del(
            self.spd.id,
            self.sa_id,
            self.local_start,
            self.local_stop,
            self.remote_start,
            self.remote_stop,
            protocol=self.proto,
            is_ipv6=self.is_ipv6,
            is_outbound=self.is_outbound,
            priority=self.priority,
            policy=self.policy,
            local_port_start=self.local_port_start,
            local_port_stop=self.local_port_stop,
            remote_port_start=self.remote_port_start,
            remote_port_stop=self.remote_port_stop,
        )
        self.stat_index = rv.stat_index
        self.test.registry.register(self, self.test.logger)
        return self

    def remove_vpp_config(self):
        self.test.vapi.ipsec_spd_entry_add_del(
            self.spd.id,
            self.sa_id,
            self.local_start,
            self.local_stop,
            self.remote_start,
            self.remote_stop,
            protocol=self.proto,
            is_ipv6=self.is_ipv6,
            is_outbound=self.is_outbound,
            priority=self.priority,
            policy=self.policy,
            local_port_start=self.local_port_start,
            local_port_stop=self.local_port_stop,
            remote_port_start=self.remote_port_start,
            remote_port_stop=self.remote_port_stop,
            is_add=0,
        )

    def object_id(self):
        return "spd-entry-%d-%d-%d-%d-%d-%d" % (
            self.spd.id,
            self.priority,
            self.policy,
            self.is_outbound,
            self.is_ipv6,
            self.remote_port_start,
        )

    def query_vpp_config(self):
        ss = self.test.vapi.ipsec_spd_dump(self.spd.id)
        for s in ss:
            if (
                s.entry.sa_id == self.sa_id
                and s.entry.is_outbound == self.is_outbound
                and s.entry.priority == self.priority
                and s.entry.policy == self.policy
                and s.entry.remote_address_start == self.remote_start
                and s.entry.remote_port_start == self.remote_port_start
            ):
                return True
        return False

    def get_stats(self, worker=None):
        c = self.test.statistics.get_counter("/net/ipsec/policy")
        if worker is None:
            total = mk_counter()
            for t in c:
                total["packets"] += t[self.stat_index]["packets"]
            return total
        else:
            # +1 to skip main thread
            return c[worker + 1][self.stat_index]


class VppIpsecSA(VppObject):
    """
    VPP SAD Entry
    """

    DEFAULT_UDP_PORT = 4500

    def __init__(
        self,
        test,
        id,
        spi,
        integ_alg,
        integ_key,
        crypto_alg,
        crypto_key,
        proto,
        tun_src=None,
        tun_dst=None,
        flags=None,
        salt=0,
        tun_flags=None,
        dscp=None,
        udp_src=None,
        udp_dst=None,
        hop_limit=None,
    ):
        e = VppEnum.vl_api_ipsec_sad_flags_t
        self.test = test
        self.id = id
        self.spi = spi
        self.integ_alg = integ_alg
        self.integ_key = integ_key
        self.crypto_alg = crypto_alg
        self.crypto_key = crypto_key
        self.proto = proto
        self.salt = salt

        self.table_id = 0
        self.tun_src = tun_src
        self.tun_dst = tun_dst
        if not flags:
            self.flags = e.IPSEC_API_SAD_FLAG_NONE
        else:
            self.flags = flags
        if tun_src:
            self.tun_src = ip_address(text_type(tun_src))
            self.flags = self.flags | e.IPSEC_API_SAD_FLAG_IS_TUNNEL
        if tun_dst:
            self.tun_dst = ip_address(text_type(tun_dst))
        self.udp_src = udp_src
        self.udp_dst = udp_dst
        self.tun_flags = (
            VppEnum.vl_api_tunnel_encap_decap_flags_t.TUNNEL_API_ENCAP_DECAP_FLAG_NONE
        )
        if tun_flags:
            self.tun_flags = tun_flags
        self.dscp = VppEnum.vl_api_ip_dscp_t.IP_API_DSCP_CS0
        if dscp:
            self.dscp = dscp
        self.hop_limit = 255
        if hop_limit:
            self.hop_limit = hop_limit

    def tunnel_encode(self):
        return {
            "src": (self.tun_src if self.tun_src else []),
            "dst": (self.tun_dst if self.tun_dst else []),
            "encap_decap_flags": self.tun_flags,
            "dscp": self.dscp,
            "hop_limit": self.hop_limit,
            "table_id": self.table_id,
        }

    def add_vpp_config(self):
        entry = {
            "sad_id": self.id,
            "spi": self.spi,
            "integrity_algorithm": self.integ_alg,
            "integrity_key": {
                "length": len(self.integ_key),
                "data": self.integ_key,
            },
            "crypto_algorithm": self.crypto_alg,
            "crypto_key": {
                "data": self.crypto_key,
                "length": len(self.crypto_key),
            },
            "protocol": self.proto,
            "tunnel": self.tunnel_encode(),
            "flags": self.flags,
            "salt": self.salt,
        }
        # don't explicitly send the defaults, let papi fill them in
        if self.udp_src:
            entry["udp_src_port"] = self.udp_src
        if self.udp_dst:
            entry["udp_dst_port"] = self.udp_dst
        r = self.test.vapi.ipsec_sad_entry_add(entry=entry)
        self.stat_index = r.stat_index
        self.test.registry.register(self, self.test.logger)
        return self

    def update_vpp_config(
        self, udp_src=None, udp_dst=None, is_tun=False, tun_src=None, tun_dst=None
    ):
        if is_tun:
            if tun_src:
                self.tun_src = ip_address(text_type(tun_src))
            if tun_dst:
                self.tun_dst = ip_address(text_type(tun_dst))
        if udp_src:
            self.udp_src = udp_src
        if udp_dst:
            self.udp_dst = udp_dst
        self.test.vapi.ipsec_sad_entry_update(
            sad_id=self.id,
            is_tun=is_tun,
            tunnel=self.tunnel_encode(),
            udp_src_port=udp_src,
            udp_dst_port=udp_dst,
        )

    def remove_vpp_config(self):
        self.test.vapi.ipsec_sad_entry_del(id=self.id)

    def object_id(self):
        return "ipsec-sa-%d" % self.id

    def query_vpp_config(self):
        e = VppEnum.vl_api_ipsec_sad_flags_t

        bs = self.test.vapi.ipsec_sa_v3_dump()
        for b in bs:
            if b.entry.sad_id == self.id:
                # if udp encap is configured then the ports should match
                # those configured or the default
                if self.flags & e.IPSEC_API_SAD_FLAG_UDP_ENCAP:
                    if not b.entry.flags & e.IPSEC_API_SAD_FLAG_UDP_ENCAP:
                        return False
                    if self.udp_src:
                        if self.udp_src != b.entry.udp_src_port:
                            return False
                    else:
                        if self.DEFAULT_UDP_PORT != b.entry.udp_src_port:
                            return False
                    if self.udp_dst:
                        if self.udp_dst != b.entry.udp_dst_port:
                            return False
                    else:
                        if self.DEFAULT_UDP_PORT != b.entry.udp_dst_port:
                            return False
                return True
        return False

    def get_stats(self, worker=None):
        c = self.test.statistics.get_counter("/net/ipsec/sa")
        if worker is None:
            total = mk_counter()
            for t in c:
                total["packets"] += t[self.stat_index]["packets"]
            return total
        else:
            # +1 to skip main thread
            return c[worker + 1][self.stat_index]

    def get_lost(self, worker=None):
        c = self.test.statistics.get_counter("/net/ipsec/sa/lost")
        if worker is None:
            total = 0
            for t in c:
                total += t[self.stat_index]
            return total
        else:
            # +1 to skip main thread
            return c[worker + 1][self.stat_index]


class VppIpsecTunProtect(VppObject):
    """
    VPP IPSEC tunnel protection
    """

    def __init__(self, test, itf, sa_out, sas_in, nh=None):
        self.test = test
        self.itf = itf
        self.sas_in = []
        for sa in sas_in:
            self.sas_in.append(sa.id)
        self.sa_out = sa_out.id
        self.nh = nh
        if not self.nh:
            self.nh = "0.0.0.0"

    def update_vpp_config(self, sa_out, sas_in):
        self.sas_in = []
        for sa in sas_in:
            self.sas_in.append(sa.id)
        self.sa_out = sa_out.id
        self.test.vapi.ipsec_tunnel_protect_update(
            tunnel={
                "sw_if_index": self.itf._sw_if_index,
                "n_sa_in": len(self.sas_in),
                "sa_out": self.sa_out,
                "sa_in": self.sas_in,
                "nh": self.nh,
            }
        )

    def object_id(self):
        return "ipsec-tun-protect-%s-%s" % (self.itf, self.nh)

    def add_vpp_config(self):
        self.test.vapi.ipsec_tunnel_protect_update(
            tunnel={
                "sw_if_index": self.itf._sw_if_index,
                "n_sa_in": len(self.sas_in),
                "sa_out": self.sa_out,
                "sa_in": self.sas_in,
                "nh": self.nh,
            }
        )
        self.test.registry.register(self, self.test.logger)

    def remove_vpp_config(self):
        self.test.vapi.ipsec_tunnel_protect_del(
            sw_if_index=self.itf.sw_if_index, nh=self.nh
        )

    def query_vpp_config(self):
        bs = self.test.vapi.ipsec_tunnel_protect_dump(sw_if_index=self.itf.sw_if_index)
        for b in bs:
            if b.tun.sw_if_index == self.itf.sw_if_index and self.nh == str(b.tun.nh):
                return True
        return False


class VppIpsecInterface(VppInterface):
    """
    VPP IPSec interface
    """

    def __init__(self, test, mode=None, instance=0xFFFFFFFF):
        super(VppIpsecInterface, self).__init__(test)

        self.mode = mode
        if not self.mode:
            self.mode = VppEnum.vl_api_tunnel_mode_t.TUNNEL_API_MODE_P2P
        self.instance = instance

    def add_vpp_config(self):
        r = self.test.vapi.ipsec_itf_create(
            itf={
                "user_instance": self.instance,
                "mode": self.mode,
            }
        )
        self.set_sw_if_index(r.sw_if_index)
        self.test.registry.register(self, self.test.logger)
        ts = self.test.vapi.ipsec_itf_dump(sw_if_index=self._sw_if_index)
        self.instance = ts[0].itf.user_instance
        return self

    def remove_vpp_config(self):
        self.test.vapi.ipsec_itf_delete(sw_if_index=self._sw_if_index)

    def query_vpp_config(self):
        ts = self.test.vapi.ipsec_itf_dump(sw_if_index=0xFFFFFFFF)
        for t in ts:
            if t.itf.sw_if_index == self._sw_if_index:
                return True
        return False

    def __str__(self):
        return self.object_id()

    def object_id(self):
        return "ipsec%d" % self.instance
