#include <gst/gst.h>

#include <unistd.h> /* getpid */

static gchar *
gst_debug_print_object (gpointer ptr)
{
  GObject *object = (GObject *) ptr;

#ifdef unused
  /* This is a cute trick to detect unmapped memory, but is unportable,
   * slow, screws around with madvise, and not actually that useful. */
  {
    int ret;

    ret = madvise ((void *) ((unsigned long) ptr & (~0xfff)), 4096, 0);
    if (ret == -1 && errno == ENOMEM) {
      buffer = g_strdup_printf ("%p (unmapped memory)", ptr);
    }
  }
#endif

  /* nicely printed object */
  if (object == NULL) {
    return g_strdup ("(NULL)");
  }
  if (*(GType *) ptr == GST_TYPE_CAPS) {
    return gst_caps_to_string ((GstCaps *) ptr);
  }
  if (*(GType *) ptr == GST_TYPE_STRUCTURE) {
    return gst_structure_to_string ((GstStructure *) ptr);
  }
#ifdef USE_POISONING
  if (*(guint32 *) ptr == 0xffffffff) {
    return g_strdup_printf ("<poisoned@%p>", ptr);
  }
#endif
  if (GST_IS_PAD (object) && GST_OBJECT_NAME (object)) {
    return g_strdup_printf ("<%s:%s>", GST_DEBUG_PAD_NAME (object));
  }
  if (GST_IS_OBJECT (object) && GST_OBJECT_NAME (object)) {
    return g_strdup_printf ("<%s>", GST_OBJECT_NAME (object));
  }
  if (G_IS_OBJECT (object)) {
    return g_strdup_printf ("<%s@%p>", G_OBJECT_TYPE_NAME (object), object);
  }

  return g_strdup_printf ("%p", ptr);
}

void
gst_debug_log_default (GstDebugCategory * category, GstDebugLevel level,
    const gchar * file, const gchar * function, gint line,
    GObject * object, GstDebugMessage * message, gpointer unused)
{
  gboolean verbose = FALSE;
  gchar *color;
  gchar *clear;
  gchar *obj;
  gchar *pidcolor;
  gint pid;
  GTimeVal now;

  if (level > gst_debug_category_get_threshold (category))
    return;

  /* color info */
  if (gst_debug_is_colored ()) {
    color =
        gst_debug_construct_term_color (gst_debug_category_get_color
        (category));
    clear = "\033[00m";
    if (verbose)
      pidcolor = g_strdup_printf ("\033[3%1dm", pid % 6 + 31);
  } else {
    color = g_strdup ("");
    clear = "";
    if (verbose)
      pidcolor = g_strdup ("");
  }

  obj = object ? gst_debug_print_object (object) : g_strdup ("");

  if (verbose) {
    pid = getpid ();
    g_get_current_time (&now);
    g_printerr ("%s (%p - %" GST_TIME_FORMAT
                ") %s%15s%s(%s%5d%s) %s%s(%d):%s:%s%s %s\n",
                gst_debug_level_get_name (level), g_thread_self (),
                GST_TIME_ARGS (GST_TIMEVAL_TO_TIME (now)),
                color, gst_debug_category_get_name (category), clear,
                pidcolor, pid, clear,
                color, file, line, function, obj, clear,
                gst_debug_message_get (message));
  } else {
    g_printerr ("%s%15.15s%s %-30.30s %s %s\n",
                color, gst_debug_category_get_name (category), clear,
                function, obj,
                gst_debug_message_get (message));
  }
    
  g_free (color);
  if (verbose)
    g_free (pidcolor);
  g_free (obj);
}
