#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <systemd/sd-bus.h>

// OpenBMC Host IPMI dbus framework
const char  *bus_name      =  "org.openbmc.HostIpmi";
const char  *object_name   =  "/org/openbmc/HostIpmi/1";
const char  *intf_name     =  "org.openbmc.HostIpmi";

//-------------------------------------------------------------------
// Gets called by PowerOff handler when a Soft Power off is requested
//-------------------------------------------------------------------
static int soft_power_off(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) 
{
	int64_t bt_resp = -1;
	int rc = 0;

	// Steps to be taken when we get this.
	// 	1: Send a SMS_ATN to the Host
	// 	2: Host receives it and sends a GetMsgFlags IPMI command
	// 	3: IPMID app handler will respond to that with a MSgFlag with bit:0x2
	// 	   set indicating we have a message for Host
	// 	4: Host sends a GetMsgBuffer command and app handler will respond to
	// 	   that with a OEM-SEL with certain fields packed indicating to the 
	// 	   host	that it do a shutdown of the partitions.   
	// 	5: Host does the partition shutdown and calls Chassis Power off command
	// 	6: App handler handles the command by making a call to ChassisManager
	// 	   Dbus
	
	// Now the job is to send the SMS_ATTN.
	
    // Req message contains the specifics about which method etc that we want to
    // access on which bus, object
    sd_bus_message *response = NULL;

	// Error return mechanism
    sd_bus_error bus_error = SD_BUS_ERROR_NULL;

	// Gets a hook onto either a SYSTEM or SESSION bus
	sd_bus *bus = (sd_bus *)ipmid_get_sd_bus_connection();

	rc = sd_bus_call_method(bus,        // On the System Bus
							bus_name,        // Service to contact
							object_name,     // Object path 
							intf_name,       // Interface name
							"setAttention",  // Method to be called
							&bus_error,      // object to return error
							&response,		 // Response buffer if any
							NULL);			 // No input arguments
	if(rc < 0)
	{
		fprintf(stderr,"ERROR initiating Power Off:[%s]\n",bus_error.message);
		goto finish;
	}

	// See if we were able to successfully raise SMS_ATN
    rc = sd_bus_message_read(response, "x", &bt_resp);
    if (rc < 0) 
	{
		fprintf(stderr, "Failed to get a rc from BT for SMS_ATN: %s\n", strerror(-rc));
		goto finish;
    }

finish:
    sd_bus_error_free(&bus_error);
    sd_bus_message_unref(response);

	if(rc < 0)
	{
		return sd_bus_reply_method_return(m, "x", rc);
	}
	else
	{
		return sd_bus_reply_method_return(m, "x", bt_resp);
	}
}

//-------------------------------------------
// Function pointer of APIs exposed via Dbus
//-------------------------------------------
static const sd_bus_vtable host_services_vtable[] =
{
	SD_BUS_VTABLE_START(0),
	// Takes No("") arguments -but- returns a value of type 64 bit integer("x")
	SD_BUS_METHOD("SoftPowerOff", "", "x", &soft_power_off, SD_BUS_VTABLE_UNPRIVILEGED),
	SD_BUS_VTABLE_END,
};

//------------------------------------------------------
// Called by IPMID as part of the start up
// -----------------------------------------------------
int start_host_service(sd_bus *bus, sd_bus_slot *slot)
{
	int rc = 0;

	/* Install the object */
	rc = sd_bus_add_object_vtable(bus,
								 &slot,
								"/org/openbmc/HostServices",  /* object path */
								"org.openbmc.HostServices",   /* interface name */
								host_services_vtable,
								NULL);
	if (rc < 0) 
	{
		fprintf(stderr, "Failed to issue method call: %s\n", strerror(-rc));
	}
	else
	{
		/* Take one in OpenBmc */
		rc = sd_bus_request_name(bus, "org.openbmc.HostServices", 0);
		if (rc < 0) 
		{
			fprintf(stderr, "Failed to acquire service name: %s\n", strerror(-rc));
		}
	}

	return rc < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
