/* GLib testing framework examples and tests
 *
 * Copyright (C) 2008-2010 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 * Author: David Zeuthen <davidz@redhat.com>
 */

#include <gio/gio.h>
#ifndef _MSC_VER
#include <unistd.h>
#endif

#include "gdbus-tests.h"

/* ---------------------------------------------------------------------------------------------------- */

typedef struct
{
  GMainLoop *loop;
  gboolean   timed_out;
} PropertyNotifyData;

static void
on_property_notify (GObject    *object,
                    GParamSpec *pspec,
                    gpointer    user_data)
{
  PropertyNotifyData *data = user_data;
  g_main_loop_quit (data->loop);
}

static gboolean
on_property_notify_timeout (gpointer user_data)
{
  PropertyNotifyData *data = user_data;
  data->timed_out = TRUE;
  g_main_loop_quit (data->loop);
  return G_SOURCE_CONTINUE;
}

gboolean
_g_assert_property_notify_run (gpointer     object,
                               const gchar *property_name)
{
  gchar *s;
  gulong handler_id;
  guint timeout_id;
  PropertyNotifyData data;

  data.loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
  data.timed_out = FALSE;
  s = g_strdup_printf ("notify::%s", property_name);
  handler_id = g_signal_connect (object,
                                 s,
                                 G_CALLBACK (on_property_notify),
                                 &data);
  g_free (s);
  timeout_id = g_timeout_add_seconds (30,
                                      on_property_notify_timeout,
                                      &data);
  g_main_loop_run (data.loop);
  g_signal_handler_disconnect (object, handler_id);
  g_source_remove (timeout_id);
  g_main_loop_unref (data.loop);

  return data.timed_out;
}

static gboolean
_give_up (gpointer data)
{
  g_error ("%s", (const gchar *) data);
  g_return_val_if_reached (G_SOURCE_CONTINUE);
}

typedef struct
{
  GMainContext *context;
  gboolean name_appeared;
  gboolean unwatch_complete;
} WatchData;

static void
name_appeared_cb (GDBusConnection *connection,
                  const gchar     *name,
                  const gchar     *name_owner,
                  gpointer         user_data)
{
  WatchData *data = user_data;

  g_assert (name_owner != NULL);
  data->name_appeared = TRUE;
  g_main_context_wakeup (data->context);
}

static void
watch_free_cb (gpointer user_data)
{
  WatchData *data = user_data;

  data->unwatch_complete = TRUE;
  g_main_context_wakeup (data->context);
}

void
ensure_gdbus_testserver_up (GDBusConnection *connection,
                            GMainContext    *context)
{
  GSource *timeout_source = NULL;
  guint watch_id;
  WatchData data = { context, FALSE, FALSE };

  g_main_context_push_thread_default (context);

  watch_id = g_bus_watch_name_on_connection (connection,
                                             "com.example.TestService",
                                             G_BUS_NAME_WATCHER_FLAGS_NONE,
                                             name_appeared_cb,
                                             NULL,
                                             &data,
                                             watch_free_cb);

  timeout_source = g_timeout_source_new_seconds (60);
  g_source_set_callback (timeout_source, _give_up,
                         "waited more than ~ 60s for gdbus-testserver to take its bus name",
                         NULL);
  g_source_attach (timeout_source, context);

  while (!data.name_appeared)
    g_main_context_iteration (context, TRUE);

  g_bus_unwatch_name (watch_id);
  watch_id = 0;

  while (!data.unwatch_complete)
    g_main_context_iteration (context, TRUE);

  g_source_destroy (timeout_source);
  g_source_unref (timeout_source);

  g_main_context_pop_thread_default (context);
}

/* ---------------------------------------------------------------------------------------------------- */

typedef struct
{
  GMainLoop *loop;
  gboolean   timed_out;
} SignalReceivedData;

static void
on_signal_received (gpointer user_data)
{
  SignalReceivedData *data = user_data;
  g_main_loop_quit (data->loop);
}

static gboolean
on_signal_received_timeout (gpointer user_data)
{
  SignalReceivedData *data = user_data;
  data->timed_out = TRUE;
  g_main_loop_quit (data->loop);
  return G_SOURCE_CONTINUE;
}

gboolean
_g_assert_signal_received_run (gpointer     object,
                               const gchar *signal_name)
{
  gulong handler_id;
  guint timeout_id;
  SignalReceivedData data;

  data.loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
  data.timed_out = FALSE;
  handler_id = g_signal_connect_swapped (object,
                                         signal_name,
                                         G_CALLBACK (on_signal_received),
                                         &data);
  timeout_id = g_timeout_add_seconds (30,
                                      on_signal_received_timeout,
                                      &data);
  g_main_loop_run (data.loop);
  g_signal_handler_disconnect (object, handler_id);
  g_source_remove (timeout_id);
  g_main_loop_unref (data.loop);

  return data.timed_out;
}

/* ---------------------------------------------------------------------------------------------------- */

GDBusConnection *
_g_bus_get_priv (GBusType            bus_type,
                 GCancellable       *cancellable,
                 GError            **error)
{
  gchar *address;
  GDBusConnection *ret;

  ret = NULL;

  address = g_dbus_address_get_for_bus_sync (bus_type, cancellable, error);
  if (address == NULL)
    goto out;

  ret = g_dbus_connection_new_for_address_sync (address,
                                                G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
                                                G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
                                                NULL, /* GDBusAuthObserver */
                                                cancellable,
                                                error);
  g_free (address);

 out:
  return ret;
}

/* ---------------------------------------------------------------------------------------------------- */
