#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <systemd/sd-bus.h>
#include <mapper.h>
#include "host-ipmid/ipmid-api.h"

void register_host_services() __attribute__((constructor));

// OpenBMC Host IPMI dbus framework
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;
    char *bus_name = NULL;

    // 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 = ipmid_get_sd_bus_connection();
    rc = mapper_get_service(bus, object_name, &bus_name);
    if (rc < 0) {
        fprintf(stderr, "Failed to get %s bus name: %s\n",
                object_name, strerror(-rc));
        goto finish;
    }
    rc = sd_bus_call_method(bus,             // In 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);
    response = sd_bus_message_unref(response);
    free(bus_name);

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

//------------------------------------------------------
// Callback register function
// -----------------------------------------------------
void register_host_services()
{
    // Gets a hook onto SYSTEM bus used by host-ipmid
    sd_bus *bus = ipmid_get_sd_bus_connection();

    // Gets a hook onto SYSTEM bus slot used by host-ipmid
    sd_bus_slot *ipmid_slot = ipmid_get_sd_bus_slot();

    //start_host_service(bus, ipmid_slot);
    start_host_service(bus, ipmid_slot);
}
