#include <sys/types.h>
#include <unistd.h>

#include <gst/gst.h>

#define SECS 5

static gboolean
handle_error_message (GstMessage * msg)
{
  GError *err = NULL;
  gchar *dbg = NULL;

  if (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ERROR)
    return FALSE;

  gst_message_parse_error (msg, &err, &dbg);
  g_error ("Error from element %s: %s\nDebug: %s\n", GST_OBJECT_NAME (msg->src),
      err->message, dbg);
  return TRUE;
}

static void
print_proc_fd (void)
{
  gchar buf[2048];
  
  g_snprintf (buf, sizeof (buf), "ls -l /proc/%u/fd/*", (guint) getpid ());
  system (buf);
  g_print ("\n\n");
}

int
main (int argc, char ** argv)
{
  GstElement *playbin, *audio_sink;
  guint pid;
  int i;

  print_proc_fd ();

  g_print ("Initializing GStreamer...\n");
  gst_init (&argc, &argv);

  if (argc < 3) {
    g_printerr ("Usage: %s URI URI [URI] [URI]\n", argv[0]);
    return -1;
  }

  print_proc_fd ();
  g_print ("Creating playbin2...\n");

  playbin = gst_element_factory_make ("playbin2", "playbin");
  g_object_add_weak_pointer (G_OBJECT (playbin), &playbin);

  print_proc_fd ();
  g_print ("Creating pulseaudiosink...\n");
  audio_sink = gst_element_factory_make ("pulseaudiosink", NULL);
  g_object_add_weak_pointer (G_OBJECT (audio_sink), &audio_sink);
//  gst_object_ref_sink (audio_sink);

  g_object_set (playbin, "audio-sink", audio_sink, NULL);
//  gst_object_unref (audio_sink);

  g_print ("Setup done.\n");

  for (i = 1; i < argc; ++i) {
    GstMessage *msg;

    print_proc_fd ();

    g_print ("Playing uri %s\n", argv[i]);
    g_object_set (playbin, "uri", argv[i], NULL);

    gst_element_set_state (playbin, GST_STATE_PLAYING);
    msg = gst_bus_timed_pop_filtered (GST_ELEMENT_BUS (playbin),
        GST_CLOCK_TIME_NONE, GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR);

    if (handle_error_message (msg))
      return -1;

    gst_message_unref (msg);

    g_print ("Playing %u secs...\n", SECS);
    msg = gst_bus_timed_pop_filtered (GST_ELEMENT_BUS (playbin),
        SECS * GST_SECOND, GST_MESSAGE_EOS | GST_MESSAGE_ERROR);

    if (msg) {
      if (handle_error_message (msg))
        return -1;

      gst_message_unref (msg);
    }

    g_print ("Stopping pipeline.\n");
    gst_element_set_state (playbin, GST_STATE_NULL);
  }

  gst_object_unref (playbin);

  print_proc_fd ();

#if 0
  if (playbin) {
    g_print ("playbin still alive!\n");
    gst_object_unref (playbin);
  }
  while (audio_sink) {
    g_print ("audio_sink still alive!\n");
    gst_object_unref (audio_sink);
  }

  print_proc_fd ();
#endif

  {
    gchar buf[2048];

    pid = (guint) getpid ();
  
    g_print ("Sleeping, hit enter to finish. PID is %u\n", pid);

    gets (buf);
  }
  return 0;
}
