#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <errno.h>

#include <openbmc_intf.h>
#include <openbmc.h>

/* ------------------------------------------------------------------------- */
static const gchar* dbus_object_path = "/org/openbmc/control";
static const gchar* instance_name = "host0";
static const gchar* dbus_name = "org.openbmc.control.Host";

static GDBusObjectManagerServer *manager = NULL;

#define PPC_BIT32(bit)          (0x80000000UL >> (bit))

#define FSI_EXTERNAL_MODE_PATH	"/sys/devices/platform/gpio-fsi/external_mode"
#define FSI_SCAN_PATH		"/sys/class/fsi-master/fsi0/rescan"

/* TODO: Change this over to the cfam path once the cfam chardev patches have landed */
#define FSI_RAW_PATH		"/sys/class/fsi-master/fsi0/slave@00:00/raw"

#define FSI_SCAN_DELAY_US	10000

/* Attention registers */
#define FSI_A_SI1S		0x081c
#define TRUE_MASK		0x100d
#define INTERRUPT_STATUS_REG	0x100b

/* SBE boot register and values */
#define SBE_VITAL		0x281c
#define SBE_WARMSTART		PPC_BIT32(0)
#define SBE_HW_TRIGGER		PPC_BIT32(2)
#define SBE_UPDATE_1ST_NIBBLE	PPC_BIT32(3)
#define SBE_IMAGE_SELECT	PPC_BIT32(8)
#define SBE_UPDATE_3RD_NIBBLE	PPC_BIT32(11)

/* Once the side is selected and attention bits are set, this starts the SBE */
#define START_SBE		(SBE_WARMSTART | SBE_HW_TRIGGER | SBE_UPDATE_1ST_NIBBLE)

/* Primary is first side. Golden is second side */
#define PRIMARY_SIDE		(SBE_HW_TRIGGER | SBE_UPDATE_1ST_NIBBLE)
#define GOLDEN_SIDE		(SBE_HW_TRIGGER | SBE_UPDATE_1ST_NIBBLE | \
				 SBE_IMAGE_SELECT | SBE_UPDATE_3RD_NIBBLE)

static gboolean
on_init(Control *control,
		GDBusMethodInvocation *invocation,
		gpointer user_data)
{
	(void) user_data;
	control_complete_init(control,invocation);
	return TRUE;
}

static gint
fsi_putcfam(int fd, uint64_t addr64, uint32_t val_host)
{
	int rc;
	uint32_t val = htobe32(val_host);
	/* Map FSI to FSI_BYTE, as the 'raw' kernel interface expects this */
	uint32_t addr = (addr64 & 0x7ffc00) | ((addr64 & 0x3ff) << 2);

	rc = lseek(fd, addr, SEEK_SET);
	if (rc < 0) {
		g_print("ERROR HostControl: cfam seek failed (0x%08x): %s\n", addr,
				strerror(errno));
		return errno;
	};

	rc = write(fd, &val, sizeof(val));
	if (rc < 0) {
		g_print("ERROR HostControl: cfam write failed: %s\n",
				strerror(errno));
		return errno;
	}

	return 0;
}

static int fsi_rescan(void)
{
	char *one = "1";
	int fd, rc;

	fd = open(FSI_SCAN_PATH, O_WRONLY);
	if (fd < 0) {
		g_print("ERROR HostControl: Failed to open path '%s': %s\n",
				FSI_SCAN_PATH, strerror(errno));
		return errno;
	}
	rc = write(fd, one, sizeof(*one));
	close(fd);
	if (rc < 0) {
		g_print("ERROR HostControl: Failed to perform FSI scan: %s\n",
				strerror(errno));
		return errno;
	}
	g_print("HostControl: Performing FSI scan (delay %d us)\n",
			FSI_SCAN_DELAY_US);
	usleep(FSI_SCAN_DELAY_US);

	return 0;
}

static gboolean
on_boot(ControlHost *host,
		GDBusMethodInvocation *invocation,
		gpointer user_data)
{
	(void) user_data;
	int rc, cfam_fd;

	if(control_host_get_debug_mode(host)==1) {
		int fd;
		char *one = "1";
		g_print("Enabling debug mode; not booting host\n");
		fd = open(FSI_EXTERNAL_MODE_PATH, O_RDWR);
		if (fd < 0) {
			g_print("ERROR HostControl: Failed to open path '%s'\n",
					FSI_EXTERNAL_MODE_PATH);
			return TRUE;
		}
		rc = write(fd, one, sizeof(*one));
		if (rc < 0) {
			g_print("ERROR HostControl: Failed to enable debug mode '%s'\n",
					FSI_EXTERNAL_MODE_PATH);
		}
		close(fd);
		return TRUE;
	}
	g_print("Booting host\n");

	rc = fsi_rescan();
	if (rc < 0)
		return FALSE;

	cfam_fd = open(FSI_RAW_PATH, O_RDWR);
	if (cfam_fd < 0) {
		g_print("ERROR HostControl: Failed to open '%s'\n", FSI_RAW_PATH);
		return FALSE;
	}

	control_host_complete_boot(host,invocation);
	do {
		rc = fsi_putcfam(cfam_fd, FSI_A_SI1S, 0x20000000);
		rc |= fsi_putcfam(cfam_fd, TRUE_MASK, 0x40000000);
		rc |= fsi_putcfam(cfam_fd, INTERRUPT_STATUS_REG, 0xFFFFFFFF);
		if(rc) { break; }

		const gchar* flash_side = control_host_get_flash_side(host);
		g_print("Using %s side of the bios flash\n",flash_side);
		if(strcmp(flash_side,"primary")==0) {
			rc |= fsi_putcfam(cfam_fd, SBE_VITAL, PRIMARY_SIDE);
		} else if(strcmp(flash_side,"golden") == 0) {
			rc |= fsi_putcfam(cfam_fd, SBE_VITAL, GOLDEN_SIDE);
		} else {
			g_print("ERROR: Invalid flash side: %s\n",flash_side);
			rc = 0xff;

		}
		if(rc) { break; }

		rc = fsi_putcfam(cfam_fd, SBE_VITAL, START_SBE);
	} while(0);
	if(rc)
	{
		g_print("ERROR HostControl: SBE sequence failed (rc=%d)\n",rc);
	}
	/* Close file descriptor */
	close(cfam_fd);

	control_host_emit_booted(host);

	return TRUE;
}

static void
on_bus_acquired(GDBusConnection *connection,
		const gchar *name,
		gpointer user_data)
{
	(void) name;
	(void) user_data;

	ObjectSkeleton *object;
	//g_print ("Acquired a message bus connection: %s\n",name);
	manager = g_dbus_object_manager_server_new(dbus_object_path);

	gchar *s;
	s = g_strdup_printf("%s/%s",dbus_object_path,instance_name);
	object = object_skeleton_new(s);
	g_free(s);

	ControlHost* control_host = control_host_skeleton_new();
	object_skeleton_set_control_host(object, control_host);
	g_object_unref(control_host);

	Control* control = control_skeleton_new();
	object_skeleton_set_control(object, control);
	g_object_unref(control);

	//define method callbacks here
	g_signal_connect(control_host,
			"handle-boot",
			G_CALLBACK(on_boot),
			object); /* user_data */
	g_signal_connect(control,
			"handle-init",
			G_CALLBACK(on_init),
			NULL); /* user_data */

	control_host_set_debug_mode(control_host,0);
	control_host_set_flash_side(control_host,"primary");

	/* Export the object (@manager takes its own reference to @object) */
	g_dbus_object_manager_server_set_connection(manager, connection);
	g_dbus_object_manager_server_export(manager, G_DBUS_OBJECT_SKELETON(object));
	g_object_unref(object);
}

static void
on_name_acquired(GDBusConnection *connection,
		const gchar *name,
		gpointer user_data)
{
	(void) connection;
	(void) name;
	(void) user_data;
	// g_print ("Acquired the name %s\n", name);
}

static void
on_name_lost(GDBusConnection *connection,
		const gchar *name,
		gpointer user_data)
{
	(void) connection;
	(void) name;
	(void) user_data;
	// g_print ("Lost the name %s\n", name);
}

gint
main(gint argc, gchar *argv[])
{
	GMainLoop *loop;
	cmdline cmd;
	cmd.argc = argc;
	cmd.argv = argv;

	guint id;
	loop = g_main_loop_new(NULL, FALSE);

	id = g_bus_own_name(DBUS_TYPE,
			dbus_name,
			G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
			G_BUS_NAME_OWNER_FLAGS_REPLACE,
			on_bus_acquired,
			on_name_acquired,
			on_name_lost,
			&cmd,
			NULL);

	g_main_loop_run(loop);

	g_bus_unown_name(id);
	g_main_loop_unref(loop);
	return 0;
}
