#ifndef __BOOTSTATE_H
#define __BOOTSTATE_H

#include <of.h>

struct bootstate *bootstate_new_from_node(const char *name, const struct device_node *node);
struct bootstate *bootstate_find_by_name(const char *name);
struct bootstate *bootstate_by_name(const char *name);
void bootstate_info(void);
int bootstate_backend_nv(struct bootstate *bootstate);
int bootstate_backend_state(struct bootstate *bootstate, const struct device_node *node);

enum {
	__BOOTCHOOSER_FLAG_ATTEMPTS_KEEP_SHIFT,
	__BOOTCHOOSER_FLAG_ATTEMPTS_DEC_SHIFT,
	__BOOTCHOOSER_FLAG_ATTEMPTS_RESET_SHIFT,
	__BOOTCHOOSER_FLAG_DEACTIVATE_ON_ZERO_ATTEMPTS_SHIFT,
	__BOOTCHOOSER_FLAG_VERBOSE_SHIFT,
	__BOOTCHOOSER_FLAG_DRYRUN_SHIFT,
	__BOOTCHOOSER_FLAG_RETRY_WITH_DEC_SHIFT,
	__BOOTCHOOSER_FLAG_WATCHDOG_ENABLE_SHIFT,
	__BOOTCHOOSER_FLAG_WATCHDOG_TIMEOUT_FROM_STATE_SHIFT,
};

#define BOOTCHOOSER_FLAG_ATTEMPTS_KEEP (1 << __BOOTCHOOSER_FLAG_ATTEMPTS_KEEP_SHIFT)
#define BOOTCHOOSER_FLAG_ATTEMPTS_DEC (1 << __BOOTCHOOSER_FLAG_ATTEMPTS_DEC_SHIFT)
#define BOOTCHOOSER_FLAG_ATTEMPTS_RESET (1 << __BOOTCHOOSER_FLAG_ATTEMPTS_RESET_SHIFT)
#define BOOTCHOOSER_FLAG_DEACTIVATE_ON_ZERO_ATTEMPTS (1 << __BOOTCHOOSER_FLAG_DEACTIVATE_ON_ZERO_ATTEMPTS_SHIFT)
#define BOOTCHOOSER_FLAG_VERBOSE (1 << __BOOTCHOOSER_FLAG_VERBOSE_SHIFT)
#define BOOTCHOOSER_FLAG_DRYRUN (1 << __BOOTCHOOSER_FLAG_DRYRUN_SHIFT)
#define BOOTCHOOSER_FLAG_RETRY_WITH_DEC (1 << __BOOTCHOOSER_FLAG_RETRY_WITH_DEC_SHIFT)
#define BOOTCHOOSER_FLAG_WATCHDOG_ENABLE (1 << __BOOTCHOOSER_FLAG_WATCHDOG_ENABLE_SHIFT)
#define BOOTCHOOSER_FLAG_WATCHDOG_TIMEOUT_FROM_STATE (1 << __BOOTCHOOSER_FLAG_WATCHDOG_TIMEOUT_FROM_STATE_SHIFT)

int bootstate_get_target(struct bootstate *bootstate, unsigned flags, char **target_out);
int bootstate_bootchooser(char *name, unsigned flags, unsigned watchdog_timeout_s);

#endif /* __BOOTSTATE_H */
