// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2018 IBM Corp.
#include <assert.h>
#include <errno.h>
#include <stdlib.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 __attribute__((unused)),
					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;
	}

	rc = sd_bus_send(NULL, n, NULL);
	sd_bus_message_unref(n);
	return rc;
}

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 __attribute__((unused)))
{
	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_set_backend(sd_bus_message *m, void *userdata,
				    sd_bus_error *ret_error __attribute__((unused)))
{
	struct mbox_context *context;
	struct backend backend;
	sd_bus_message *n;
	const char *name;
	int rc;

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

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

	if (!strcmp(name, "vpnor")) {
		struct vpnor_partition_paths paths;

		vpnor_default_paths(&paths);
		backend = backend_get_vpnor();
		rc = control_set_backend(context, &backend, &paths);
		if (rc < 0)
			return rc;
	} else if (!strcmp(name, "mtd")) {
		char **paths = NULL;
		char *path = NULL;

		rc = sd_bus_message_read_strv(m, &paths);
		if (rc < 0)
			return rc;

		if (paths && *paths)
			path = *paths;
		else
			path = get_dev_mtd();

		backend = backend_get_mtd();

		rc = control_set_backend(context, &backend, path);
		if (rc < 0)
			return rc;

		free(path);
		free(paths);
	} else if (!strcmp(name, "file")) {
		char **paths = NULL;
		char *path = NULL;

		rc = sd_bus_message_read_strv(m, &paths);
		if (rc < 0)
			return rc;

		if (!(paths && *paths))
			return -EINVAL;

		path = *paths;

		backend = backend_get_file();

		rc = control_set_backend(context, &backend, path);
		if (rc < 0)
			return rc;

		free(path);
		free(paths);
	} else {
		return -EINVAL;
	}

	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;
	}

	rc = sd_bus_send(NULL, n, NULL);
	sd_bus_message_unref(n);
	return rc;
}

static int control_dbus_get_u8(sd_bus *bus __attribute__((unused)),
			       const char *path,
			       const char *interface __attribute__((unused)),
			       const char *property,
			       sd_bus_message *reply, void *userdata,
			       sd_bus_error *ret_error __attribute__((unused)))
{
	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_METHOD("SetBackend", "sas", NULL, &control_dbus_set_backend,
		      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;
}
