// SPDX-License-Identifier: GPL-2.0+
/*
 * Events provide a general-purpose way to react to / subscribe to changes
 * within U-Boot
 *
 * Copyright 2021 Google LLC
 * Written by Simon Glass <sjg@chromium.org>
 */

#define LOG_CATEGORY	LOGC_EVENT

#include <common.h>
#include <event.h>
#include <event_internal.h>
#include <log.h>
#include <linker_lists.h>
#include <malloc.h>
#include <asm/global_data.h>
#include <linux/list.h>

DECLARE_GLOBAL_DATA_PTR;

#if CONFIG_IS_ENABLED(EVENT_DEBUG)
const char *const type_name[] = {
	"none",
	"test",

	/* Events related to driver model */
	"dm_post_init",
	"dm_pre_probe",
	"dm_post_probe",
	"dm_pre_remove",
	"dm_post_remove",

	/* init hooks */
	"misc_init_f",
};

_Static_assert(ARRAY_SIZE(type_name) == EVT_COUNT, "event type_name size");
#endif

static const char *event_type_name(enum event_t type)
{
#if CONFIG_IS_ENABLED(EVENT_DEBUG)
	return type_name[type];
#else
	return "(unknown)";
#endif
}

static int notify_static(struct event *ev)
{
	struct evspy_info *start =
		ll_entry_start(struct evspy_info, evspy_info);
	const int n_ents = ll_entry_count(struct evspy_info, evspy_info);
	struct evspy_info *spy;

	for (spy = start; spy != start + n_ents; spy++) {
		if (spy->type == ev->type) {
			int ret;

			log_debug("Sending event %x/%s to spy '%s'\n", ev->type,
				  event_type_name(ev->type), event_spy_id(spy));
			ret = spy->func(NULL, ev);

			/*
			 * TODO: Handle various return codes to
			 *
			 * - claim an event (no others will see it)
			 * - return an error from the event
			 */
			if (ret)
				return log_msg_ret("spy", ret);
		}
	}

	return 0;
}

static int notify_dynamic(struct event *ev)
{
	struct event_state *state = gd_event_state();
	struct event_spy *spy, *next;

	list_for_each_entry_safe(spy, next, &state->spy_head, sibling_node) {
		if (spy->type == ev->type) {
			int ret;

			log_debug("Sending event %x/%s to spy '%s'\n", ev->type,
				  event_type_name(ev->type), spy->id);
			ret = spy->func(spy->ctx, ev);

			/*
			 * TODO: Handle various return codes to
			 *
			 * - claim an event (no others will see it)
			 * - return an error from the event
			 */
			if (ret)
				return log_msg_ret("spy", ret);
		}
	}

	return 0;
}

int event_notify(enum event_t type, void *data, int size)
{
	struct event event;
	int ret;

	event.type = type;
	if (size > sizeof(event.data))
		return log_msg_ret("size", -E2BIG);
	memcpy(&event.data, data, size);

	ret = notify_static(&event);
	if (ret)
		return log_msg_ret("dyn", ret);

	if (CONFIG_IS_ENABLED(EVENT_DYNAMIC)) {
		ret = notify_dynamic(&event);
		if (ret)
			return log_msg_ret("dyn", ret);
	}

	return 0;
}

int event_notify_null(enum event_t type)
{
	return event_notify(type, NULL, 0);
}

void event_show_spy_list(void)
{
	struct evspy_info *start =
		ll_entry_start(struct evspy_info, evspy_info);
	const int n_ents = ll_entry_count(struct evspy_info, evspy_info);
	struct evspy_info *spy;
	const int size = sizeof(ulong) * 2;

	printf("Seq  %-24s  %*s  %s\n", "Type", size, "Function", "ID");
	for (spy = start; spy != start + n_ents; spy++) {
		printf("%3x  %-3x %-20s  %*p  %s\n", (uint)(spy - start),
		       spy->type, event_type_name(spy->type), size, spy->func,
		       event_spy_id(spy));
	}
}

#if CONFIG_IS_ENABLED(EVENT_DYNAMIC)
static void spy_free(struct event_spy *spy)
{
	list_del(&spy->sibling_node);
}

int event_register(const char *id, enum event_t type, event_handler_t func, void *ctx)
{
	struct event_state *state = gd_event_state();
	struct event_spy *spy;

	if (!CONFIG_IS_ENABLED(EVENT_DYNAMIC))
		return -ENOSYS;
	spy = malloc(sizeof(*spy));
	if (!spy)
		return log_msg_ret("alloc", -ENOMEM);

	spy->id = id;
	spy->type = type;
	spy->func = func;
	spy->ctx = ctx;
	list_add_tail(&spy->sibling_node, &state->spy_head);

	return 0;
}

int event_uninit(void)
{
	struct event_state *state = gd_event_state();
	struct event_spy *spy, *next;

	list_for_each_entry_safe(spy, next, &state->spy_head, sibling_node)
		spy_free(spy);

	return 0;
}

int event_init(void)
{
	struct event_state *state = gd_event_state();

	INIT_LIST_HEAD(&state->spy_head);

	return 0;
}
#endif /* EVENT_DYNAMIC */
