/* 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>
#include <unistd.h>
#include <string.h>

#include "gdbus-tests.h"

/* all tests rely on a global connection */
static GDBusConnection *c = NULL;

/* all tests rely on a shared mainloop */
static GMainLoop *loop = NULL;

/* ---------------------------------------------------------------------------------------------------- */
/* Check that pending calls fail with G_IO_ERROR_CLOSED if the connection is closed  */
/* See https://bugzilla.gnome.org/show_bug.cgi?id=660637 */
/* ---------------------------------------------------------------------------------------------------- */

static void
sleep_cb (GObject      *source_object,
          GAsyncResult *res,
          gpointer      user_data)
{
  GError **error = user_data;
  GVariant *result;

  result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, error);
  g_assert (result == NULL);
  g_main_loop_quit (loop);
}

static gboolean
on_timeout (gpointer user_data)
{
  /* tear down bus */
  session_bus_stop ();
  return G_SOURCE_REMOVE;
}

static void
test_connection_loss (void)
{
  GDBusProxy *proxy;
  GError *error;

  error = NULL;
  proxy = g_dbus_proxy_new_sync (c,
                                 G_DBUS_PROXY_FLAGS_NONE,
                                 NULL,                      /* GDBusInterfaceInfo */
                                 "com.example.TestService", /* name */
                                 "/com/example/TestObject", /* object path */
                                 "com.example.Frob",        /* interface */
                                 NULL, /* GCancellable */
                                 &error);
  g_assert_no_error (error);

  error = NULL;
  g_dbus_proxy_call (proxy,
                     "Sleep",
                     g_variant_new ("(i)", 100 * 1000 /* msec */),
                     G_DBUS_CALL_FLAGS_NONE,
                     10 * 1000 /* msec */,
                     NULL, /* GCancellable */
                     sleep_cb,
                     &error);

  /* Make sure we don't exit when the bus goes away */
  g_dbus_connection_set_exit_on_close (c, FALSE);

  /* Nuke the connection to the bus */
  g_timeout_add (100 /* ms */, on_timeout, NULL);

  g_main_loop_run (loop);

  /* If we didn't act on connection-loss we'd be getting G_IO_ERROR_TIMEOUT
   * generated locally. So if we get G_IO_ERROR_CLOSED it means that we
   * are acting correctly on connection loss.
   */
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED);
  g_assert (!g_dbus_error_is_remote_error (error));
  g_clear_error (&error);

  g_object_unref (proxy);
}

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

int
main (int   argc,
      char *argv[])
{
  GError *error;
  gint ret;
  gchar *path;

  g_test_init (&argc, &argv, NULL);

  /* all the tests rely on a shared main loop */
  loop = g_main_loop_new (NULL, FALSE);

  session_bus_up ();

  /* this is safe; testserver will exit once the bus goes away */
  path = g_test_build_filename (G_TEST_BUILT, "gdbus-testserver", NULL);
  g_assert (g_spawn_command_line_async (path, NULL));
  g_free (path);

  /* Create the connection in the main thread */
  error = NULL;
  c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
  g_assert_no_error (error);
  g_assert (c != NULL);

  ensure_gdbus_testserver_up (c, NULL);

  g_test_add_func ("/gdbus/connection-loss", test_connection_loss);

  ret = g_test_run();

  g_object_unref (c);

  session_bus_down ();

  g_main_loop_unref (loop);

  return ret;
}
