#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <glib.h>
#include <gio/gio.h>
#include <libsoup/soup.h>

SoupSession *session;
SoupURI *uri;
GMainLoop *loop;

/* Do a bunch of sync calls */
void *thread_fn(void *data)
{
    static char req[] = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
                        " <D:propfind xmlns:D=\"DAV:\">\n"
                        "  <D:prop>\n"
                        "<D:creationdate/>\n"
                        "<D:displayname/>\n"
                        "<D:getcontentlength/>\n"
                        "<D:getcontenttype/>\n"
                        "<D:getetag/>\n"
                        "<D:getlastmodified/>\n"
                        "<D:resourcetype/>\n"
                        "  </D:prop>\n"
                        " </D:propfind>\n";

    /* GMainContext *worker_context = g_main_context_new(); */
    /* g_main_context_push_thread_default (worker_context); */

    for (;;) {
        SoupMessage *msg = soup_message_new_from_uri (SOUP_METHOD_PROPFIND, uri);
        soup_message_headers_append (msg->request_headers, "Depth", "0");
        soup_message_set_request (msg, "application/xml", SOUP_MEMORY_STATIC, req, strlen(req));
        soup_session_send_message (session, msg);
        g_object_unref(msg);
    }
}

/* Do a bunch of async calls */
static void
read_cb (GObject *object, GAsyncResult *result, gpointer user_data);

static void
close_cb (GObject *object, GAsyncResult *result, gpointer user_data)
{
    SoupRequest *req;
    GError *error = NULL;
    g_input_stream_close_finish(G_INPUT_STREAM (object), result, &error);
    if (error) {
        printf("close_cb error: %s\n", error->message);
        exit(0);
    }

    req = soup_session_request_uri (session, uri, NULL);
    soup_request_send_async (req, NULL, read_cb, NULL);

    g_object_unref (object);
}

static void
read_cb (GObject *object, GAsyncResult *result, gpointer user_data)
{
    GError *error = NULL;
    GInputStream *stream = soup_request_send_finish (SOUP_REQUEST (object), result, &error);
    if (error) {
        printf("read_cb error: %s\n", error->message);
        exit(0);
    }
    g_input_stream_close_async(stream, 0, NULL, close_cb, NULL);
    g_object_unref (object);
}

int main()
{
    SoupSessionFeature *cookie_jar;
    SoupRequest *req;

    loop = g_main_loop_new(NULL, FALSE);

    session = soup_session_new_with_options ("user-agent", "gvfs/", NULL);

    uri = soup_uri_new("http://127.0.0.1:8080/deleteme.txt");

    g_object_set (session, "ssl-strict", FALSE, NULL);

    cookie_jar = g_object_new (SOUP_TYPE_COOKIE_JAR, NULL);
    soup_session_add_feature (session, cookie_jar);
    g_object_unref (cookie_jar);

    g_object_set (session, "accept-language-auto", TRUE, NULL);

    /* Logging */
    if (0) {
        SoupLogger         *logger;
        SoupLoggerLogLevel  level;

        level = SOUP_LOGGER_LOG_BODY;

        logger = soup_logger_new (level, 100000);
        soup_session_add_feature (session, SOUP_SESSION_FEATURE (logger));
        g_object_unref (logger);
    }

    g_thread_new("worker", thread_fn, NULL);

    req = soup_session_request_uri (session, uri, NULL);
    soup_request_send_async (req, NULL, read_cb, NULL);
    g_main_loop_run(loop);

    return 0;
}
