#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <openbmc_intf.h>
#include <openbmc.h>
#include <gpio.h>
#include <gpio_configs.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 GpioConfigs g_gpio_configs;

static GDBusObjectManagerServer *manager = NULL;

static GPIO* fsi_data;
static GPIO* fsi_clk;
static GPIO* fsi_enable;
static GPIO* cronus_sel;
static size_t num_optionals;
static GPIO* optionals;
static gboolean* optional_pols;

/* Bit bang patterns */

//putcfam pu 281c 30000000 -p0 (Primary Side Select)
static const char* primary = "000011111111110101111000111001100111111111111111111111111111101111111111";
//putcfam pu 281c B0000000 -p0
static const char* go = "000011111111110101111000111000100111111111111111111111111111101101111111";
//putcfam pu 0x281c 30900000 (Golden Side Select)
static const char* golden = "000011111111110101111000111001100111101101111111111111111111101001111111";

/* Setup attentions */
//putcfam pu 0x081C 20000000
static const char* attnA = "000011111111111101111110001001101111111111111111111111111111110001111111";
//putcfam pu 0x100D 40000000
static const char* attnB = "000011111111111011111100101001011111111111111111111111111111110001111111";
//putcfam pu 0x100B FFFFFFFF
static const char* attnC = "000011111111111011111101001000000000000000000000000000000000001011111111";



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

int
fsi_bitbang(const char* pattern)
{
	int rc=GPIO_OK;
	int i;
	for(i=0;i<strlen(pattern);i++) {
		rc = gpio_writec(fsi_data,pattern[i]);
		if(rc!=GPIO_OK) { break; }
		rc = gpio_clock_cycle(fsi_clk,1);
		if(rc!=GPIO_OK) { break; }
	}
	return rc;
}

int
fsi_standby()
{
	int rc=GPIO_OK;
	rc = gpio_write(fsi_data,1);
	if(rc!=GPIO_OK) { return rc; }
	rc = gpio_clock_cycle(fsi_clk,5000);
	if(rc!=GPIO_OK) { return rc; }
	return rc;
}


static gboolean
on_boot(ControlHost *host,
		GDBusMethodInvocation *invocation,
		gpointer user_data)
{
	int rc = GPIO_OK;
	GDBusProxy *proxy;
	GError *error = NULL;
	GDBusConnection *connection =
		g_dbus_object_manager_server_get_connection(manager);

	if (!(fsi_data && fsi_clk && fsi_enable && cronus_sel)) {
		g_print("ERROR invalid GPIO configuration, will not boot\n");
		return FALSE;
	}
	if(control_host_get_debug_mode(host)==1) {
		g_print("Enabling debug mode; not booting host\n");
		rc |= gpio_open(fsi_enable);
		rc |= gpio_open(cronus_sel);
		rc |= gpio_write(fsi_enable,1);
		rc |= gpio_write(cronus_sel,0);
		if(rc!=GPIO_OK) {
			g_print("ERROR enabling debug mode: %d\n",rc);
		}
		return TRUE;
	}
	g_print("Booting host\n");
	Control* control = object_get_control((Object*)user_data);
	control_host_complete_boot(host,invocation);
	do {
		rc = gpio_open(fsi_clk);
		rc |= gpio_open(fsi_data);
		rc |= gpio_open(fsi_enable);
		rc |= gpio_open(cronus_sel);
		for (size_t i = 0; i < num_optionals; ++i) {
			rc |= gpio_open(&optionals[i]);
		}
		if(rc!=GPIO_OK) { break; }

		//setup dc pins
		rc = gpio_write(cronus_sel,1);
		rc |= gpio_write(fsi_enable,1);
		rc |= gpio_write(fsi_clk,1);
		for (size_t i = 0; i < num_optionals; ++i) {
			rc |= gpio_write(&optionals[i], optional_pols[i]);
		}
		if(rc!=GPIO_OK) { break; }

		//data standy state
		rc = fsi_standby();

		//clear out pipes
		rc |= gpio_write(fsi_data,0);
		rc |= gpio_clock_cycle(fsi_clk,256);
		rc |= gpio_write(fsi_data,1);
		rc |= gpio_clock_cycle(fsi_clk,50);
		if(rc!=GPIO_OK) { break; }

		rc = fsi_bitbang(attnA);
		rc |= fsi_standby();

		rc |= fsi_bitbang(attnB);
		rc |= fsi_standby();

		rc |= fsi_bitbang(attnC);
		rc |= fsi_standby();
		if(rc!=GPIO_OK) { 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_bitbang(primary);
		} else if(strcmp(flash_side,"golden") == 0) {
			rc |= fsi_bitbang(golden);
		} else {
			g_print("ERROR: Invalid flash side: %s\n",flash_side);
			rc = 0xff;

		}
		rc |= fsi_standby();
		if(rc!=GPIO_OK) { break; }

		rc = fsi_bitbang(go);

		rc |= gpio_write(fsi_data,1); /* Data standby state */
		rc |= gpio_clock_cycle(fsi_clk,2);

		rc |= gpio_write(fsi_clk,0); /* hold clk low for clock mux */
		rc |= gpio_write(fsi_enable,0);
		rc |= gpio_clock_cycle(fsi_clk,16);
		rc |= gpio_write(fsi_clk,0); /* Data standby state */

	} while(0);
	if(rc != GPIO_OK)
	{
		g_print("ERROR HostControl: GPIO sequence failed (rc=%d)\n",rc);
	} else {
		control_emit_goto_system_state(control,"HOST_BOOTING");
	}
	gpio_close(fsi_clk);
	gpio_close(fsi_data);
	gpio_close(fsi_enable);
	gpio_close(cronus_sel);
	for (size_t i = 0; i < num_optionals; ++i) {
		gpio_close(&optionals[i]);
	}

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

	if(read_gpios(connection, &g_gpio_configs) != TRUE) {
		g_print("ERROR Hostctl: could not read GPIO configuration\n");
		return;
	}

	fsi_data = &g_gpio_configs.hostctl_gpio.fsi_data;
	fsi_clk = &g_gpio_configs.hostctl_gpio.fsi_clk;
	fsi_enable = &g_gpio_configs.hostctl_gpio.fsi_enable;
	cronus_sel = &g_gpio_configs.hostctl_gpio.cronus_sel;
	num_optionals = g_gpio_configs.hostctl_gpio.num_optionals;
	optionals = g_gpio_configs.hostctl_gpio.optionals;
	optional_pols = g_gpio_configs.hostctl_gpio.optional_pols;

	gpio_init(connection, fsi_data);
	gpio_init(connection, fsi_clk);
	gpio_init(connection, fsi_enable);
	gpio_init(connection, cronus_sel);
	for (int i = 0; i < num_optionals; ++i) {
		gpio_init(connection, &optionals[i]);
	}
}

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);
	free_gpios(&g_gpio_configs);
}

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