#include <string.h>

#include <openbmc_intf.h>
#include <openbmc.h>
#include <gpio.h>

static const gchar* dbus_object_path = "/org/openbmc/control";
static const gchar* object_name = "/org/openbmc/control/checkstop0";
static const gchar* dbus_name = "org.openbmc.control.Checkstop";

static GDBusObjectManagerServer *manager = NULL;

GPIO checkstop = (GPIO){ "CHECKSTOP" };

static bool
is_host_booted(GDBusConnection* connection)
{
    GDBusProxy *proxy;
    GError *error;
    GVariant *parm = NULL;
    GVariant *result = NULL;

    error = NULL;
    proxy = g_dbus_proxy_new_sync(connection,
            G_DBUS_PROXY_FLAGS_NONE,
            NULL, /* GDBusInterfaceInfo* */
            "org.openbmc.managers.System", /* name */
            "/org/openbmc/managers/System", /* object path */
            "org.openbmc.managers.System", /* interface name */
            NULL, /* GCancellable */
            &error);
    g_assert_no_error(error);

    error = NULL;
    result = g_dbus_proxy_call_sync(proxy,
            "getSystemState",
            parm,
            G_DBUS_CALL_FLAGS_NONE,
            -1,
            NULL,
            &error);
    g_assert_no_error(error);

    gchar *system_state;
    g_variant_get(result,"(s)",&system_state);
    g_variant_unref(result);

    if ((strcmp(system_state, "HOST_BOOTED") == 0) ||
        (strcmp(system_state, "HOST_BOOTING")== 0)) {
        return true;
    }

    return false;
}

static gboolean
chassis_reboot(gpointer connection)
{
    int rc = 0;
    uint8_t gpio = 0;
    GDBusProxy *proxy;
    GError *error;
    GVariant *parm = NULL;
    GVariant *result = NULL;

    // The gpio line may flicker during power on/off, so check that the value
    // is still 0 (checkstopped) and that host is booted in order to reboot
    rc = gpio_open(&checkstop);
    if (rc != GPIO_OK) {
        return FALSE;
    }
    rc = gpio_read(&checkstop, &gpio);
    if (rc != GPIO_OK) {
        gpio_close(&checkstop);
        return FALSE;
    }
    gpio_close(&checkstop);
    if ((!gpio) && (is_host_booted(connection)))
    {
        printf("Host Checkstop, rebooting host\n");
        error = NULL;
        proxy = g_dbus_proxy_new_sync((GDBusConnection*)connection,
            G_DBUS_PROXY_FLAGS_NONE,
            NULL, /* GDBusInterfaceInfo* */
            "org.openbmc.control.Chassis", /* name */
            "/org/openbmc/control/chassis0", /* object path */
            "org.openbmc.control.Chassis", /* interface name */
            NULL, /* GCancellable */
            &error);
        g_assert_no_error(error);

        error = NULL;
        result = g_dbus_proxy_call_sync(proxy,
            "reboot",
            parm,
            G_DBUS_CALL_FLAGS_NONE,
            -1,
            NULL,
            &error);
        g_assert_no_error(error);
    }

    return FALSE;
}

static gboolean
on_checkstop_interrupt(GIOChannel *channel,
        GIOCondition condition,
        gpointer connection)
{
    GError *error = 0;
    gsize bytes_read = 0;
    gchar buf[2];
    buf[1] = '\0';

    g_io_channel_seek_position( channel, 0, G_SEEK_SET, 0 );
    g_io_channel_read_chars(channel,
            buf, 1,
            &bytes_read,
            &error );
    printf("checkstop gpio: %s\n",buf);

    if(checkstop.irq_inited) {
        // Need to wait at least 10s for the SBE to gather failure data.
        // Also the user may be monitoring the system and reset the system
        // themselves. So wait an arbitrary time of 30s (and check that the
        // gpio value is still 0) before issuing reboot.
        g_timeout_add(30000, chassis_reboot, connection);
    }
    else {
        checkstop.irq_inited = true;
    }

    return TRUE;
}

static void
on_bus_acquired(GDBusConnection *connection,
        const gchar *name,
        gpointer object)
{
    int rc = GPIO_OK;
    manager = g_dbus_object_manager_server_new(dbus_object_path);

    ControlCheckstop* control_checkstop = control_checkstop_skeleton_new();
    object_skeleton_set_control_checkstop(object, control_checkstop);
    g_object_unref(control_checkstop);

    g_dbus_object_manager_server_set_connection(manager, connection);

    rc = gpio_init(connection, &checkstop);
    if (rc == GPIO_OK) {
        rc = gpio_open_interrupt(&checkstop, on_checkstop_interrupt, connection);
    }
    if (rc != GPIO_OK) {
        printf("ERROR Checkstop: GPIO setup (rc=%d)\n", rc);
    }
    g_dbus_object_manager_server_export(manager, G_DBUS_OBJECT_SKELETON(object));
}

static void
on_name_acquired(GDBusConnection *connection,
        const gchar *name,
        gpointer object)
{
}

static void
on_name_lost(GDBusConnection *connection,
        const gchar *name,
        gpointer object)
{
}

gint
main(gint argc, gchar *argv[])
{
    GMainLoop *loop;
    ObjectSkeleton *newobject;

    newobject = object_skeleton_new(object_name);

    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,
            newobject,
            NULL);

    g_main_loop_run(loop);

    g_bus_unown_name(id);
    g_object_unref(newobject);
    g_main_loop_unref(loop);
    return 0;
}

