#include <libgupnp/gupnp.h>
#include <pthread.h>

typedef struct {
        GMainContext *main_context;
        GMainLoop *main_loop;
        GUPnPContextManager *cm;
} ThreadData;

void
on_context_available (GUPnPContextManager *cm,
                      GUPnPContext        *context,
                      gpointer             user_data)
{
        g_debug ("Thread: %p", pthread_self ());
        g_debug ("====> New context for interface %s",
                 gssdp_client_get_interface (GSSDP_CLIENT(context)));
}

void
on_context_unavailable (GUPnPContextManager *cm,
                      GUPnPContext        *context,
                      gpointer             user_data)
{
        g_debug ("Thread: %p", pthread_self ());
        g_debug ("====> Context for interface %s gone",
                 gssdp_client_get_interface (GSSDP_CLIENT(context)));
}


GUPnPContextManager *
setup_context_manager (ThreadData *data)
{
        GUPnPContextManager *cm;

        cm = gupnp_context_manager_create (0);
        g_signal_connect (cm, "context-available", G_CALLBACK (on_context_available), data);
        g_signal_connect (cm, "context-unavailable", G_CALLBACK (on_context_unavailable), data);

        return cm;
}

void *thread_func (gpointer user_data)
{
        g_debug ("Worker Thread: %p", pthread_self ());
        ThreadData *thread_data = g_new0 (ThreadData, 1);

        thread_data->main_context = g_main_context_new ();
        thread_data->main_loop = g_main_loop_new (thread_data->main_context, FALSE);
        g_main_context_push_thread_default (thread_data->main_context);

        setup_context_manager (thread_data);

        g_main_loop_run (thread_data->main_loop);
        g_main_context_pop_thread_default (thread_data->main_context);

        g_main_context_unref (thread_data->main_context);
        g_main_loop_unref (thread_data->main_loop);

        g_free (thread_data);

        return NULL;
}

int main()
{
        g_thread_init (NULL);
        g_type_init ();

        g_debug ("Main Thread: %p", pthread_self ());
        GMainLoop *main_loop;

        g_thread_create (thread_func, NULL, FALSE, NULL);

        main_loop = g_main_loop_new (NULL, FALSE);
        g_main_loop_run (main_loop);

        g_main_loop_unref (main_loop);
        return 0;
}
