/*
 * Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
 *
 * global.c: Test global parameter setting/getting
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gst/gst.h>

#define THREAD_COUNT	5
#define ITERATIONS	20

/* stupid logging functions */
static void
gst_debug_log_one (GstDebugCategory * category,
    GstDebugLevel level,
    const gchar * file,
    const gchar * function,
    gint line, GObject * object, GstDebugMessage * message, gpointer data)
    G_GNUC_NO_INSTRUMENT;
     static void gst_debug_log_two (GstDebugCategory * category,
    GstDebugLevel level,
    const gchar * file,
    const gchar * function,
    gint line, GObject * object, GstDebugMessage * message, gpointer thread)
  G_GNUC_NO_INSTRUMENT;

     static void
         gst_debug_log_one (GstDebugCategory * category, GstDebugLevel level,
    const gchar * file, const gchar * function, gint line, GObject * object,
    GstDebugMessage * message, gpointer data)
{
}
static void
gst_debug_log_two (GstDebugCategory * category, GstDebugLevel level,
    const gchar * file, const gchar * function, gint line, GObject * object,
    GstDebugMessage * message, gpointer data)
{
}

static gpointer
thread_main (gpointer threadnum)
{
  gint num;
  gint i;

  num = GPOINTER_TO_INT (threadnum);
  for (i = 0; i < ITERATIONS; i++) {
    g_print ("iteration %d of thread %d starting\n", i, num);
    /* do some stuff with global settings */
    gst_debug_set_default_threshold (GST_LEVEL_DEBUG);
    gst_debug_add_log_function (gst_debug_log_one, g_thread_self ());
    gst_debug_add_log_function (gst_debug_log_two, NULL);

    /* reset all the stuff we did */
    gst_debug_set_default_threshold (GST_LEVEL_DEFAULT);
    g_assert (gst_debug_remove_log_function_by_data (g_thread_self ()) == 1);
  }

  g_print ("Thread %d is done.\n", num);
  return threadnum;
}

gint
main (gint argc, gchar * argv[])
{
  gint i;
  GThread *threads[THREAD_COUNT];

  g_print ("initializing GStreamer\n");
  gst_init (&argc, &argv);
  g_assert (gst_debug_remove_log_function (gst_debug_log_default) == 1);

  /* some checks for defaults */
  g_print ("Doing startup checks\n");
  g_assert (gst_debug_get_default_threshold () == GST_LEVEL_DEFAULT);

  g_print ("creating %d threads\n", THREAD_COUNT);
  for (i = 0; i < THREAD_COUNT; i++) {
    g_assert ((threads[i] =
            g_thread_create (thread_main, GINT_TO_POINTER (i), TRUE, NULL)));
  }
  g_print ("joining %d threads\n", THREAD_COUNT);
  for (i = 0; i < THREAD_COUNT; i++) {
    g_assert (GPOINTER_TO_INT (g_thread_join (threads[i])) == i);
  }

  /* some checks if everything worked */
  g_print ("Doing shutdown checks\n");
  g_assert (gst_debug_get_default_threshold () == GST_LEVEL_DEFAULT);
  g_assert (gst_debug_remove_log_function (gst_debug_log_two) ==
      THREAD_COUNT * ITERATIONS);

  return 0;
}
