/* Compile with:
 *   gcc `pkg-config --libs --cflags glib-2.0 gobject-2.0 libsoup-2.2` -o p pause.c
 *
 * The retrieved page is printed to stdout, debug messages are printed to
 * stderr.
 *
 * To get an URL:
 *   ./pause http://www.google.com/
 *
 * To get a file served by the internal server:
 *   ./pause
 */

#include <stdlib.h>
#include <string.h>
#include <signal.h>

#include <glib.h>
#include <glib-object.h>

#include <libsoup/soup.h>
#include <libsoup/soup.h>
#include <libsoup/soup-server.h>
#include <libsoup/soup-server-message.h>


static GMainLoop *loop;

static void
sighandler (int sig) {
  g_main_loop_quit (loop);
}

static void
server_cb (SoupServerContext *context,
           SoupMessage *msg,
           gpointer user_data)
{
  const SoupUri *uri = soup_message_get_uri (msg);
  gint i;

  g_printerr ("[server] Requested '%s'\n", uri->path);

  soup_message_set_status (msg, SOUP_STATUS_OK);
  soup_server_message_set_encoding (SOUP_SERVER_MESSAGE (msg), SOUP_TRANSFER_CHUNKED);

  for (i = 0; i < 5; i++)
    {
      soup_message_add_chunk (msg, SOUP_BUFFER_STATIC, "X", 1);
      soup_message_io_unpause (msg);
    }

  soup_message_add_final_chunk (msg);
  soup_message_io_unpause (msg);

  g_main_loop_quit (loop);
}

static void
start_server ()
{
  SoupServer *server;

  server = soup_server_new ("port", 8001, NULL, NULL);
  soup_server_add_handler (server, NULL, NULL, server_cb, NULL, NULL);

  g_printerr ("[server] Starting HTTP server\n");
  soup_server_run_async (server);
}

static void
received_chunk_cb (SoupMessage *msg,
                   gpointer user_data)
{
  g_printerr ("[client] Got chunk (%d bytes)\n", msg->response.length);

  write (1, msg->response.body, msg->response.length);

  /* BUG */
  soup_message_io_pause (msg);
  soup_message_io_unpause (msg);
}

static void
finished_chunks_cb (SoupMessage *msg,
                    gpointer user_data)
{
  g_printerr ("[client] Done\n");
  g_main_loop_quit (loop);
}

static void
start_client (const gchar *url)
{
  SoupSession *session;
  SoupMessage *msg;

  session = soup_session_async_new ();
  msg = soup_message_new (SOUP_METHOD_GET, url);
  soup_message_set_flags (msg, SOUP_MESSAGE_OVERWRITE_CHUNKS);
  g_signal_connect (msg, "got_chunk", G_CALLBACK (received_chunk_cb), NULL);
  soup_session_queue_message (session, msg, finished_chunks_cb, NULL);
}

int
main (int argc,
      char **argv)
{
  gchar *url;
  gboolean need_server;

  if (argc > 1)
    {
      url = argv[1];
      need_server = FALSE;
    }
  else
    {
      url = "http://localhost:8001/";
      need_server = TRUE;
    }

  g_type_init ();
  g_thread_init (NULL);

  loop = g_main_loop_new (NULL, FALSE);
  signal (SIGINT, sighandler);

  if (need_server && fork () > 0)
    start_server ();
  else
    start_client (url);

  g_main_loop_run (loop);
  g_main_loop_unref (loop);

  return 0;
}

