#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <syslog.h>
#include "interfaces/openbmc_intf.h"
#include "openbmc.h"
#include "gpio.h"

/* ---------------------------------------------------------------------------------------------------- */
static const gchar* dbus_object_path = "/org/openbmc/control";
static const gchar* dbus_name        = "org.openbmc.control.Power";

//This object will use these GPIOs
GPIO power_pin    = (GPIO){ "POWER_PIN" };
GPIO pgood        = (GPIO){ "PGOOD" };

static GDBusObjectManagerServer *manager = NULL;

//guint tmp_pgood = 0;
//guint last_pgood = 0;
time_t pgood_timeout_start = 0;

static gboolean poll_pgood(gpointer user_data)
{
	ControlPower *control_power = object_get_control_power((Object*)user_data);
	Control* control = object_get_control((Object*)user_data);

	//send the heartbeat
	control_emit_heartbeat(control,dbus_name);
	const gchar* obj_path = g_dbus_object_get_object_path((GDBusObject*)user_data);

	guint poll_int = control_get_poll_interval(control);
	if (poll_int == 0)
	{
		printf("ERROR PowerControl: Poll interval cannot be 0\n");
		return FALSE;
	}
	//handle timeout
	time_t current_time = time(NULL);
	if (difftime(current_time,pgood_timeout_start) > control_power_get_pgood_timeout(control_power)
		&& pgood_timeout_start != 0)
	{
		printf("ERROR PowerControl: Pgood poll timeout\n");
		// set timeout to 0 so timeout doesn't happen again
		control_power_set_pgood_timeout(control_power,0);
		pgood_timeout_start = 0;
		return TRUE;
	}
	uint8_t gpio;
	
	int rc = gpio_open(&pgood);
	rc = gpio_read(&pgood,&gpio);
	gpio_close(&pgood);	
	if (rc == GPIO_OK)
	{
		//if changed, set property and emit signal
		if (gpio != control_power_get_pgood(control_power))
		{
 			control_power_set_pgood(control_power,gpio);
 			if (gpio==0)
 			{
 				control_power_emit_power_lost(control_power);
				control_emit_goto_system_state(control,"POWERED_OFF");
 			}
 			else
 			{
 				control_power_emit_power_good(control_power);
				control_emit_goto_system_state(control,"POWERED_ON");
 			}
		}
	} else {
		printf("ERROR PowerControl: GPIO read error (gpio=%s,rc=%d)\n",pgood.name,rc);
	}
	//pgood is not at desired state yet
	if (gpio != control_power_get_state(control_power) &&
		control_power_get_pgood_timeout(control_power) > 0)
	{
		if (pgood_timeout_start == 0 ) {
			pgood_timeout_start = current_time;
		}
	}
	else 
	{
		pgood_timeout_start = 0;
	}
	return TRUE;
}



static gboolean
on_set_power_state (ControlPower          *pwr,
                GDBusMethodInvocation  *invocation,
                guint                   state,
                gpointer                user_data)
{
	Control* control = object_get_control((Object*)user_data);
	const gchar* obj_path = g_dbus_object_get_object_path((GDBusObject*)user_data);
	if (state > 1)
	{
		g_dbus_method_invocation_return_dbus_error (invocation,
                                                "org.openbmc.ControlPower.Error.Failed",
                                                "Invalid power state");
		return TRUE;
	}
	// return from method call
	control_power_complete_set_power_state(pwr,invocation);
	if (state == control_power_get_state(pwr))
	{
		g_print("Power already at requested state: %d\n",state);
	}
	else
	{
		int error = 0;
		do {
			if (state == 1) {
				control_emit_goto_system_state(control,"POWERING_ON");
			} else {
				control_emit_goto_system_state(control,"POWERING_OFF");
			}
			error = gpio_open(&power_pin);
			if (error != GPIO_OK) { break;	}
			error = gpio_write(&power_pin,!state);
			if (error != GPIO_OK) { break;	}
			gpio_close(&power_pin);
			control_power_set_state(pwr,state);
		} while(0);
		if (error != GPIO_OK)
		{
			printf("ERROR PowerControl: GPIO set power state (rc=%d)\n",error);
		}
	}
	return TRUE;
}

static gboolean
on_init (Control         *control,
         GDBusMethodInvocation  *invocation,
         gpointer                user_data)
{
	pgood_timeout_start = 0;
	guint poll_interval = control_get_poll_interval(control);
	g_timeout_add(poll_interval, poll_pgood, user_data);
	control_complete_init(control,invocation);
	return TRUE;
}

static gboolean
on_get_power_state (ControlPower          *pwr,
                GDBusMethodInvocation  *invocation,
                gpointer                user_data)
{
	guint pgood = control_power_get_pgood(pwr);
	control_power_complete_get_power_state(pwr,invocation,pgood);
	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;
	if (cmd->argc < 2)
	{
		g_print("No objects created.  Put object name(s) on command line\n");
		return;
	}	
  	manager = g_dbus_object_manager_server_new (dbus_object_path);
	gchar *s;
  	s = g_strdup_printf ("%s/%s",dbus_object_path,cmd->argv[1]);
	g_print("%s\n",s);
  	object = object_skeleton_new (s);
  	g_free (s);

	ControlPower* control_power = control_power_skeleton_new ();
	object_skeleton_set_control_power (object, control_power);
	g_object_unref (control_power);
	
	Control* control = control_skeleton_new ();
	object_skeleton_set_control (object, control);
	g_object_unref (control);

	//define method callbacks here
	g_signal_connect (control_power,
       	            "handle-set-power-state",
               	    G_CALLBACK (on_set_power_state),
               	    object); /* user_data */

	g_signal_connect (control_power,
               	    "handle-get-power-state",
               	    G_CALLBACK (on_get_power_state),
               	    NULL); /* user_data */

	g_signal_connect (control,
               	    "handle-init",
               	    G_CALLBACK (on_init),
               	    object); /* 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,&power_pin);
		if (rc != GPIO_OK) { break; }
		rc = gpio_init(connection,&pgood);
		if (rc != GPIO_OK) { break; }
		uint8_t gpio;
		rc = gpio_open(&pgood);
		if (rc != GPIO_OK) { break; }
		rc = gpio_read(&pgood,&gpio);
		if (rc != GPIO_OK) { break; }
		gpio_close(&pgood);	
		control_power_set_pgood(control_power,gpio);
	} while(0);
	if (rc != GPIO_OK)
	{
		printf("ERROR PowerControl: GPIO setup (rc=%d)\n",rc);
	} 
}

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)
{
}




/*----------------------------------------------------------------*/
/* Main Event Loop                                                */

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 (G_BUS_TYPE_SESSION,
                       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;
}
