#include "stdlib.h"
#include "stdio.h"
#include "unistd.h"

#include "glib.h"
#include "libsoup/soup.h"

static GMainLoop *loop;
static SoupSession *session;

static void session_cb(SoupSession *session, SoupMessage *msg, gpointer user_data)
{
    const char *name, *value;
    int i = 0;
    SoupMessageHeaders *hdrs;
    SoupMessageHeadersIter iter;
    SoupAddress *address = soup_message_get_address(msg);

    g_object_get(G_OBJECT(msg), "response-headers", &hdrs, NULL);

    soup_message_headers_iter_init(&iter, hdrs);

    printf("=== session_cb() : %s ===\n", soup_address_get_name(address));

    /* print headers */
    while (soup_message_headers_iter_next(&iter, &name, &value)) {
        if (i == 0)
            printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
        printf("%s: %s\n", name, value);
        i++;
    }
    if (i > 0)
        printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
}

static void connection_disconnected_cb(GObject *connection, gpointer user_data)
{
    printf("*** Connection disconnected.\n");
}

static void connection_created_cb(SoupSession *session, GObject *connection, gpointer user_data)
{
    printf("*** Connection created.\n");
    g_signal_connect(connection, "disconnected", G_CALLBACK(connection_disconnected_cb), NULL);
}

static void setup_soup(const char *url_ok, const char *url_noack)
{
    SoupMessage *msg;

    session = soup_session_async_new();

    g_signal_connect(session, "connection-created", G_CALLBACK(connection_created_cb), NULL);

    //g_object_set(G_OBJECT(session), "timeout", 5, NULL);

    msg = soup_message_new("GET", url_ok);
    if (msg == NULL)
        exit(1);
    soup_session_queue_message(session, msg, session_cb, NULL);

    msg = soup_message_new("GET", url_noack);
    if (msg == NULL)
        exit(1);
    soup_session_queue_message(session, msg, session_cb, NULL);
}

static gboolean cleanup_soup_cb(gpointer data)
{
    printf("cleanup_soup_cb()\n");
    g_object_unref(session);
    g_main_loop_quit(loop);
    return FALSE;
}

gboolean abort_soup_cb(gpointer data)
{
    printf ("soup_session_abort()\n");
    soup_session_abort(session);
    return FALSE;
}

int main (int argc, char **argv)
{
    if (argc != 3) {
        printf("usage: %s uri1 uri2\n", argv[0]);
        return EXIT_FAILURE;
    }

    g_type_init();
    setup_soup(argv[1], argv[2]);
   
    loop = g_main_loop_new(NULL, FALSE);

    g_timeout_add(3000, abort_soup_cb, NULL);
    g_timeout_add(5000, cleanup_soup_cb, NULL);

    printf("About to start GMainLoop..\n");
    g_main_loop_run(loop);
    g_main_loop_unref(loop);
    printf("GMainLoop quit. Run netstat and lsof to confirm there are [no] fd leaks.\n");
    printf("Calling pause()\n");

    pause(); // wait for os signal

    return EXIT_SUCCESS;
}
