#include <stdio.h>
#include "interfaces/openbmc_intf.h"
#include "gpio.h"
#include "openbmc.h"
#include "object_mapper.h"

/* ------------------------------------------------------------------------- */
static const gchar* dbus_object_path = "/org/openbmc/buttons";
static const gchar* instance_name = "power0";
static const gchar* dbus_name = "org.openbmc.buttons.Power";
static const int LONG_PRESS_SECONDS = 3;
static GDBusObjectManagerServer *manager = NULL;

//This object will use these GPIOs
GPIO gpio_button = (GPIO){ "POWER_BUTTON" };

static gboolean
on_is_on(Button *btn,
		GDBusMethodInvocation *invocation,
		gpointer user_data)
{
	gboolean btn_state=button_get_state(btn);
	button_complete_is_on(btn,invocation,btn_state);
	return TRUE;
}

static gboolean
on_button_press(Button *btn,
		GDBusMethodInvocation *invocation,
		gpointer user_data)
{
	button_emit_pressed(btn);
	button_complete_sim_press(btn,invocation);
	return TRUE;
}

static gboolean
on_button_interrupt( GIOChannel *channel,
		GIOCondition condition,
		gpointer user_data )
{
	GError *error = 0;
	gsize bytes_read = 0;
	gchar buf[2];
	buf[1] = '\0';
	g_io_channel_seek_position( channel, 0, G_SEEK_SET, 0 );
	g_io_channel_read_chars(channel,
			buf, 1,
			&bytes_read,
			&error );
	printf("%s\n",buf);

	time_t current_time = time(NULL);
	if(gpio_button.irq_inited)
	{
		Button* button = object_get_button((Object*)user_data);
		if(buf[0] == '0')
		{
			printf("Power Button pressed\n");
			button_emit_pressed(button);
			button_set_timer(button,(long)current_time);
		}
		else
		{
			long press_time = current_time-button_get_timer(button);
			printf("Power Button released, held for %ld seconds\n",press_time);
			if(press_time > LONG_PRESS_SECONDS)
			{
				button_emit_pressed_long(button);
			} else {
				button_emit_released(button);
			}
		}
	}
	else { gpio_button.irq_inited = true; }

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

	Button* button = button_skeleton_new();
	object_skeleton_set_button(object, button);
	g_object_unref(button);

	ObjectMapper* mapper = object_mapper_skeleton_new();
	object_skeleton_set_object_mapper(object, mapper);
	g_object_unref(mapper);

	//define method callbacks
	g_signal_connect(button,
			"handle-is-on",
			G_CALLBACK(on_is_on),
			NULL); /* user_data */
	g_signal_connect(button,
			"handle-sim-press",
			G_CALLBACK(on_button_press),
			NULL); /* user_data */


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

	/* Export all objects */
	g_dbus_object_manager_server_set_connection(manager, connection);

	// get gpio device paths
	int rc = GPIO_OK;
	do {
		rc = gpio_init(connection,&gpio_button);
		if(rc != GPIO_OK) { break; }
		rc = gpio_open_interrupt(&gpio_button,on_button_interrupt,object);
		if(rc != GPIO_OK) { break; }
	} while(0);
	if(rc != GPIO_OK)
	{
		printf("ERROR PowerButton: GPIO setup (rc=%d)\n",rc);
	}
	emit_object_added((GDBusObjectManager*)manager);
}

static void
on_name_acquired(GDBusConnection *connection,
		const gchar *name,
		gpointer user_data)
{
}

static void
on_name_lost(GDBusConnection *connection,
		const gchar *name,
		gpointer user_data)
{
}

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