#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)
{
	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)
{
	int rc, cfam_fd;
	GDBusProxy *proxy;
	GError *error = NULL;
	GDBusConnection *connection =
		g_dbus_object_manager_server_get_connection(manager);

	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* control = object_get_control((Object*)user_data);
	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)
{
	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)
{
	// g_print ("Acquired the name %s\n", name);
}

static void
on_name_lost(GDBusConnection *connection,
		const gchar *name,
		gpointer 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;
}
