/* 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 TRUE;
}

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 (TRUE);
}

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 TRUE;
}

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;
}

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