from ipaddress import IPv4Address, AddressValueError
from vpp_object import VppObject


class AuthMethod:
    v = {"rsa-sig": 1, "shared-key": 2}

    @staticmethod
    def value(key):
        return AuthMethod.v[key]


class IDType:
    v = {"ip4-addr": 1, "fqdn": 2, "ip6-addr": 5}

    @staticmethod
    def value(key):
        return IDType.v[key]


class Profile(VppObject):
    """IKEv2 profile"""

    def __init__(self, test, profile_name):
        self.test = test
        self.vapi = test.vapi
        self.profile_name = profile_name
        self.udp_encap = False
        self.natt = True

    def disable_natt(self):
        self.natt = False

    def add_auth(self, method, data, is_hex=False):
        if isinstance(method, int):
            m = method
        elif isinstance(method, str):
            m = AuthMethod.value(method)
        else:
            raise Exception("unsupported type {}".format(method))
        self.auth = {"auth_method": m, "data": data, "is_hex": is_hex}

    def add_local_id(self, id_type, data):
        if isinstance(id_type, str):
            t = IDType.value(id_type)
        self.local_id = {"id_type": t, "data": data, "is_local": True}

    def add_remote_id(self, id_type, data):
        if isinstance(id_type, str):
            t = IDType.value(id_type)
        self.remote_id = {"id_type": t, "data": data, "is_local": False}

    def add_local_ts(
        self, start_addr, end_addr, start_port=0, end_port=0xFFFF, proto=0, is_ip4=True
    ):
        self.ts_is_ip4 = is_ip4
        self.local_ts = {
            "is_local": True,
            "protocol_id": proto,
            "start_port": start_port,
            "end_port": end_port,
            "start_addr": start_addr,
            "end_addr": end_addr,
        }

    def add_remote_ts(
        self, start_addr, end_addr, start_port=0, end_port=0xFFFF, proto=0
    ):
        try:
            IPv4Address(start_addr)
            is_ip4 = True
        except AddressValueError:
            is_ip4 = False
        self.ts_is_ip4 = is_ip4
        self.remote_ts = {
            "is_local": False,
            "protocol_id": proto,
            "start_port": start_port,
            "end_port": end_port,
            "start_addr": start_addr,
            "end_addr": end_addr,
        }

    def add_responder_hostname(self, hn):
        self.responder_hostname = hn

    def add_responder(self, responder):
        self.responder = responder

    def add_ike_transforms(self, tr):
        self.ike_transforms = tr

    def add_esp_transforms(self, tr):
        self.esp_transforms = tr

    def set_udp_encap(self, udp_encap):
        self.udp_encap = udp_encap

    def set_lifetime_data(self, data):
        self.lifetime_data = data

    def set_ipsec_over_udp_port(self, port):
        self.ipsec_udp_port = {"is_set": 1, "port": port}

    def set_tunnel_interface(self, sw_if_index):
        self.tun_itf = sw_if_index

    def object_id(self):
        return "ikev2-profile-%s" % self.profile_name

    def remove_vpp_config(self):
        self.vapi.ikev2_profile_add_del(name=self.profile_name, is_add=False)

    def add_vpp_config(self):
        self.vapi.ikev2_profile_add_del(name=self.profile_name, is_add=True)
        if hasattr(self, "auth"):
            self.vapi.ikev2_profile_set_auth(
                name=self.profile_name, data_len=len(self.auth["data"]), **self.auth
            )
        if hasattr(self, "local_id"):
            self.vapi.ikev2_profile_set_id(
                name=self.profile_name,
                data_len=len(self.local_id["data"]),
                **self.local_id,
            )
        if hasattr(self, "remote_id"):
            self.vapi.ikev2_profile_set_id(
                name=self.profile_name,
                data_len=len(self.remote_id["data"]),
                **self.remote_id,
            )
        if hasattr(self, "local_ts"):
            self.vapi.ikev2_profile_set_ts(name=self.profile_name, ts=self.local_ts)

        if hasattr(self, "remote_ts"):
            self.vapi.ikev2_profile_set_ts(name=self.profile_name, ts=self.remote_ts)

        if hasattr(self, "responder"):
            self.vapi.ikev2_set_responder(
                name=self.profile_name, responder=self.responder
            )

        if hasattr(self, "responder_hostname"):
            print(self.responder_hostname)
            self.vapi.ikev2_set_responder_hostname(
                name=self.profile_name, **self.responder_hostname
            )

        if hasattr(self, "ike_transforms"):
            self.vapi.ikev2_set_ike_transforms(
                name=self.profile_name, tr=self.ike_transforms
            )

        if hasattr(self, "esp_transforms"):
            self.vapi.ikev2_set_esp_transforms(
                name=self.profile_name, tr=self.esp_transforms
            )

        if self.udp_encap:
            self.vapi.ikev2_profile_set_udp_encap(name=self.profile_name)

        if hasattr(self, "lifetime_data"):
            self.vapi.ikev2_set_sa_lifetime(
                name=self.profile_name, **self.lifetime_data
            )

        if hasattr(self, "ipsec_udp_port"):
            self.vapi.ikev2_profile_set_ipsec_udp_port(
                name=self.profile_name, **self.ipsec_udp_port
            )
        if hasattr(self, "tun_itf"):
            self.vapi.ikev2_set_tunnel_interface(
                name=self.profile_name, sw_if_index=self.tun_itf
            )

        if not self.natt:
            self.vapi.ikev2_profile_disable_natt(name=self.profile_name)

    def query_vpp_config(self):
        res = self.vapi.ikev2_profile_dump()
        for r in res:
            if r.profile.name == self.profile_name:
                return r.profile
        return None
