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