#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 = "reset0";
static const gchar* dbus_name        = "org.openbmc.buttons.reset";
static const int LONG_PRESS_SECONDS = 3;
static GDBusObjectManagerServer *manager = NULL;

//This object will use these GPIOs
GPIO gpio_button    = (GPIO){ "RESET_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 );
	GIOStatus rc = 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("reset 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("reset 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);
 	cmdline *cmd = user_data;
  	manager = g_dbus_object_manager_server_new (dbus_object_path);
  	int i=0;
	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;
}

