// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2018 IBM Corp.
#include <assert.h>
#include <errno.h>
#include <systemd/sd-bus.h>

#include "common.h"
#include "dbus.h"
#include "control_dbus.h"
#include "mbox.h"

typedef int (*control_action)(struct mbox_context *context);

static int control_dbus_directive(sd_bus_message *m, void *userdata,
					sd_bus_error *ret_error,
					control_action action)
{
	struct mbox_context *context;
	sd_bus_message *n;
	int rc;

	if (!action) {
		MSG_ERR("No action provided\n");
		return -EINVAL; 
	}

	context = (struct mbox_context *) userdata;
	if (!context) {
		MSG_ERR("DBUS Internal Error\n");
		return -EINVAL;
	}

	rc = action(context);
	if (rc < 0) {
		MSG_ERR("Action failed: %d\n", rc);
		return rc;
	}

	rc = sd_bus_message_new_method_return(m, &n);
	if (rc < 0) {
		MSG_ERR("sd_bus_message_new_method_return failed: %d\n", rc);
		return rc;
	}

	return sd_bus_send(NULL, n, NULL);
}

static int control_dbus_ping(sd_bus_message *m, void *userdata,
				   sd_bus_error *ret_error)
{
	return control_dbus_directive(m, userdata, ret_error, control_ping);
}

static int control_dbus_reset(sd_bus_message *m, void *userdata,
				    sd_bus_error *ret_error)
{
	return control_dbus_directive(m, userdata, ret_error, control_reset);
}

static int control_dbus_kill(sd_bus_message *m, void *userdata,
				   sd_bus_error *ret_error)
{
	return control_dbus_directive(m, userdata, ret_error, control_kill);
}

static int control_dbus_modified(sd_bus_message *m, void *userdata,
				       sd_bus_error *ret_error)
{
	return control_dbus_directive(m, userdata, ret_error, control_modified);
}

static int control_dbus_suspend(sd_bus_message *m, void *userdata,
				      sd_bus_error *ret_error)
{
	return control_dbus_directive(m, userdata, ret_error, control_suspend);
}

static int control_dbus_resume(sd_bus_message *m, void *userdata,
				     sd_bus_error *ret_error)
{
	struct mbox_context *context;
	sd_bus_message *n;
	bool modified;
	int rc;

	context = (struct mbox_context *) userdata;
	if (!context) {
		MSG_ERR("DBUS Internal Error\n");
		return -EINVAL;
	}

	rc = sd_bus_message_read_basic(m, 'b', &modified);
	if (rc < 0) {
		MSG_ERR("DBUS error reading message: %s\n", strerror(-rc));
		return rc;
	}

	rc = control_resume(context, modified);
	if (rc < 0)
		return rc;

	rc = sd_bus_message_new_method_return(m, &n);
	if (rc < 0) {
		MSG_ERR("sd_bus_message_new_method_return failed: %d\n", rc);
		return rc;
	}

	return sd_bus_send(NULL, n, NULL);
}

static int control_dbus_get_u8(sd_bus *bus, const char *path,
			       const char *interface, const char *property,
			       sd_bus_message *reply, void *userdata,
			       sd_bus_error *ret_error)
{
	struct mbox_context *context = userdata;
	uint8_t value;

	assert(!strcmp(MBOX_DBUS_OBJECT, path));

	if (!strcmp("DaemonState", property)) {
		value = control_daemon_state(context);
	} else if (!strcmp("LpcState", property)) {
		value = control_lpc_state(context);
	} else {
		MSG_ERR("Unknown DBus property: %s\n", property);
		return -EINVAL;
	}

	return sd_bus_message_append(reply, "y", value);
}

static const sd_bus_vtable mboxd_vtable[] = {
	SD_BUS_VTABLE_START(0),
	SD_BUS_METHOD("Ping", NULL, NULL, &control_dbus_ping,
		      SD_BUS_VTABLE_UNPRIVILEGED),
	SD_BUS_METHOD("Reset", NULL, NULL, &control_dbus_reset,
		      SD_BUS_VTABLE_UNPRIVILEGED),
	SD_BUS_METHOD("Kill", NULL, NULL, &control_dbus_kill,
		      SD_BUS_VTABLE_UNPRIVILEGED),
	SD_BUS_METHOD("MarkFlashModified", NULL, NULL, &control_dbus_modified,
		      SD_BUS_VTABLE_UNPRIVILEGED),
	SD_BUS_METHOD("Suspend", NULL, NULL, &control_dbus_suspend,
		      SD_BUS_VTABLE_UNPRIVILEGED),
	SD_BUS_METHOD("Resume", "b", NULL, &control_dbus_resume,
		      SD_BUS_VTABLE_UNPRIVILEGED),
	SD_BUS_PROPERTY("DaemonState", "y", &control_dbus_get_u8, 0,
		        SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
	SD_BUS_PROPERTY("LpcState", "y", &control_dbus_get_u8, 0,
		        SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
	SD_BUS_VTABLE_END
};

int control_dbus_init(struct mbox_context *context)
{
	return sd_bus_add_object_vtable(context->bus, NULL,
					MBOX_DBUS_OBJECT,
					MBOX_DBUS_CONTROL_IFACE,
					mboxd_vtable, context);
}

#define __unused __attribute__((unused))
void control_dbus_free(struct mbox_context *context __unused)
{
	return;
}
