// 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 "mboxd.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;
}
