#ifndef DYNBH_H
#define DYNBH_H

#ifdef DYNBH
#include <libubox/list.h>
#include <libubus.h>
#include <cmdu.h>
#include <stdbool.h>
#include <stdint.h>
#include <timer_impl.h>

#define MAP_UPLINK_PATH 	"/var/run/multiap/multiap.backhaul"

#ifdef PERSIST_CONTROLLER
enum cntlr_discovery_mode {
	DYNAMIC_CNTLR_MODE_AUTO,
	DYNAMIC_CNTLR_MODE_DISABLED,
	DYNAMIC_CNTLR_MODE_CONTROLLER,
	DYNAMIC_CNTLR_MODE_UNKNOWN,
};
#endif

enum dynbh_port_state {
	PORT_STATE_DISCOVERY,
	PORT_STATE_UPLINK,
	PORT_STATE_LAN,
	PORT_STATE_LOOP,
#ifdef PERSIST_CONTROLLER
	PORT_STATE_DHCP_SERVER,
#endif
	PORT_STATE_UNKNOWN,
};

struct ethport {
	char ifname[16];
	uint8_t macaddr[6];
	uint8_t operstate;
	enum dynbh_port_state state;
	uint8_t num_mid;
	uint16_t mid[32];
	atimer_t port_discovery;
	int discovery_attempts;
	struct list_head list;
	struct dynbh_ctx *ctx;
};

struct dynbh_ctx {
	uint32_t oid;
	uint32_t map_oid;
	void *subscriber;
	int queued_searches;
	struct list_head ethportlist;
	struct ubus_object obj;
};

struct agent;

extern int (* const dbh_ftable[])(struct agent *a, struct cmdu_buff *cmdu);

bool dynbh_is_enabled(struct agent *a);

const char *port_state_to_str(enum dynbh_port_state state);
#ifdef PERSIST_CONTROLLER
const char *dynbh_mode_to_str(enum cntlr_discovery_mode mode);
enum cntlr_discovery_mode dynbh_str_to_mode(const char *mode);
#endif

int dynbh_publish_object(struct agent *a, const char *objname);

struct ethport *dynbh_get_ethport(struct dynbh_ctx *p, const char *ifname);

void dynbh_port_connected(struct agent *a, struct ethport *port);
void dynbh_port_disconnected(struct agent *a, struct ethport *port);

void dynbh_free(struct agent *a);
void dynbh_init(struct agent *a);
#endif
#endif
