from vpp_object import VppObject


class VppDHCPProxy(VppObject):

    def __init__(
        self,
        test,
        dhcp_server,
        dhcp_src_address,
        rx_vrf_id=0,
        server_vrf_id=0,
    ):
        self._test = test
        self._rx_vrf_id = rx_vrf_id
        self._server_vrf_id = server_vrf_id
        self._dhcp_server = dhcp_server
        self._dhcp_src_address = dhcp_src_address

    def set_proxy(
            self,
            dhcp_server,
            dhcp_src_address,
            rx_vrf_id=0,
            server_vrf_id=0):
        if self.query_vpp_config():
            raise Exception('Vpp config present')
        self._rx_vrf_id = rx_vrf_id
        self._server_vrf_id = server_vrf_id
        self._dhcp_server = dhcp_server
        self._dhcp_src_address = dhcp_src_address

    def add_vpp_config(self):
        self._test.vapi.dhcp_proxy_config(
            is_add=1,
            rx_vrf_id=self._rx_vrf_id,
            server_vrf_id=self._server_vrf_id,
            dhcp_server=self._dhcp_server,
            dhcp_src_address=self._dhcp_src_address)
        self._test.registry.register(self, self._test.logger)

    def remove_vpp_config(self):
        self._test.vapi.dhcp_proxy_config(
            rx_vrf_id=self._rx_vrf_id,
            server_vrf_id=self._server_vrf_id,
            dhcp_server=self._dhcp_server,
            dhcp_src_address=self._dhcp_src_address,
            is_add=0)

    def get_vpp_dump(self):
        dump = self._test.vapi.dhcp_proxy_dump()
        for entry in dump:
            if entry.rx_vrf_id == self._rx_vrf_id:
                return entry

    def query_vpp_config(self):
        dump = self.get_vpp_dump()
        return True if dump else False

    def object_id(self):
        return "dhcp-proxy-%d" % self._rx_vrf_id


class VppDHCPClient(VppObject):

    def __init__(
            self,
            test,
            sw_if_index,
            hostname,
            id=None,
            want_dhcp_event=False,
            set_broadcast_flag=True,
            dscp=None,
            pid=None):
        self._test = test
        self._sw_if_index = sw_if_index
        self._hostname = hostname
        self._id = id
        self._want_dhcp_event = want_dhcp_event
        self._set_broadcast_flag = set_broadcast_flag
        self._dscp = dscp
        self._pid = pid

    def set_client(
            self,
            sw_if_index,
            hostname,
            id=None,
            want_dhcp_event=False,
            set_broadcast_flag=True,
            dscp=None,
            pid=None):
        if self.query_vpp_config():
            raise Exception('Vpp config present')
        self._sw_if_index = sw_if_index
        self._hostname = hostname
        self._id = id
        self._want_dhcp_event = want_dhcp_event
        self._set_broadcast_flag = set_broadcast_flag
        self._dscp = dscp
        self._pid = pid

    def add_vpp_config(self):
        id = self._id.encode('ascii') if self._id else None
        client = {'sw_if_index': self._sw_if_index, 'hostname': self._hostname,
                  'id': id,
                  'want_dhcp_event': self._want_dhcp_event,
                  'set_broadcast_flag': self._set_broadcast_flag,
                  'dscp': self._dscp, 'pid': self._pid}
        self._test.vapi.dhcp_client_config(is_add=1, client=client)
        self._test.registry.register(self, self._test.logger)

    def remove_vpp_config(self):
        client = client = {
            'sw_if_index': self._sw_if_index,
            'hostname': self._hostname}
        self._test.vapi.dhcp_client_config(client=client, is_add=0)

    def get_vpp_dump(self):
        dump = self._test.vapi.dhcp_client_dump()
        for entry in dump:
            if entry.client.sw_if_index == self._sw_if_index:
                return entry

    def query_vpp_config(self):
        dump = self.get_vpp_dump()
        return True if dump else False

    def object_id(self):
        return "dhcp-client-%s/%d" % (self._hostname, self._sw_if_index)
