/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright (C) 2009 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 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, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Author: Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"
#include "gasyncinitable.h"
#include "gasyncresult.h"
#include "gsimpleasyncresult.h"
#include "glibintl.h"


/**
 * SECTION:gasyncinitable
 * @short_description: Asynchronously failable object initialization interface
 * @include: gio/gio.h
 * @see_also: #GInitable
 *
 * This is the asynchronous version of #GInitable; it behaves the same
 * in all ways except that initialization is asynchronous. For more details
 * see the descriptions on #GInitable.
 *
 * A class may implement both the #GInitable and #GAsyncInitable interfaces.
 *
 * Users of objects implementing this are not intended to use the interface
 * method directly; instead it will be used automatically in various ways.
 * For C applications you generally just call g_async_initable_new_async()
 * directly, or indirectly via a foo_thing_new_async() wrapper. This will call
 * g_async_initable_init_async() under the cover, calling back with %NULL and
 * a set %GError on failure.
 *
 * A typical implementation might look something like this:
 *
 * |[
 * enum {
 *    NOT_INITIALIZED,
 *    INITIALIZING,
 *    INITIALIZED
 * };
 *
 * static void
 * _foo_ready_cb (Foo *self)
 * {
 *   GList *l;
 *
 *   self->priv->state = INITIALIZED;
 *
 *   for (l = self->priv->init_results; l != NULL; l = l->next)
 *     {
 *       GSimpleAsyncResult *simple = l->data;
 *
 *       if (!self->priv->success)
 *         g_simple_async_result_set_error (simple, ...);
 *
 *       g_simple_async_result_complete (simple);
 *       g_object_unref (simple);
 *     }
 *
 *   g_list_free (self->priv->init_results);
 *   self->priv->init_results = NULL;
 * }
 *
 * static void
 * foo_init_async (GAsyncInitable       *initable,
 *                 int                   io_priority,
 *                 GCancellable         *cancellable,
 *                 GAsyncReadyCallback   callback,
 *                 gpointer              user_data)
 * {
 *   Foo *self = FOO (initable);
 *   GSimpleAsyncResult *simple;
 *
 *   simple = g_simple_async_result_new (G_OBJECT (initable)
 *                                       callback,
 *                                       user_data,
 *                                       foo_init_async);
 *
 *   switch (self->priv->state)
 *     {
 *       case NOT_INITIALIZED:
 *         _foo_get_ready (self);
 *         self->priv->init_results = g_list_append (self->priv->init_results,
 *                                                   simple);
 *         self->priv->state = INITIALIZING;
 *         break;
 *       case INITIALIZING:
 *         self->priv->init_results = g_list_append (self->priv->init_results,
 *                                                   simple);
 *         break;
 *       case INITIALIZED:
 *         if (!self->priv->success)
 *           g_simple_async_result_set_error (simple, ...);
 *
 *         g_simple_async_result_complete_in_idle (simple);
 *         g_object_unref (simple);
 *         break;
 *     }
 * }
 *
 * static gboolean
 * foo_init_finish (GAsyncInitable       *initable,
 *                  GAsyncResult         *result,
 *                  GError              **error)
 * {
 *   g_return_val_if_fail (g_simple_async_result_is_valid (result,
 *       G_OBJECT (initable), foo_init_async), FALSE);
 *
 *   if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
 *           error))
 *     return FALSE;
 *
 *   return TRUE;
 * }
 *
 * static void
 * foo_async_initable_iface_init (gpointer g_iface,
 *                                gpointer data)
 * {
 *   GAsyncInitableIface *iface = g_iface;
 *
 *   iface->init_async = foo_init_async;
 *   iface->init_finish = foo_init_finish;
 * }
 * ]|
 */

static void     g_async_initable_real_init_async  (GAsyncInitable       *initable,
						   int                   io_priority,
						   GCancellable         *cancellable,
						   GAsyncReadyCallback   callback,
						   gpointer              user_data);
static gboolean g_async_initable_real_init_finish (GAsyncInitable       *initable,
						   GAsyncResult         *res,
						   GError              **error);


typedef GAsyncInitableIface GAsyncInitableInterface;
G_DEFINE_INTERFACE (GAsyncInitable, g_async_initable, G_TYPE_OBJECT)


static void
g_async_initable_default_init (GAsyncInitableInterface *iface)
{
  iface->init_async = g_async_initable_real_init_async;
  iface->init_finish = g_async_initable_real_init_finish;
}

/**
 * g_async_initable_init_async:
 * @initable: a #GAsyncInitable.
 * @io_priority: the <link linkend="io-priority">I/O priority</link>
 *     of the operation.
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 * @callback: a #GAsyncReadyCallback to call when the request is satisfied
 * @user_data: the data to pass to callback function
 *
 * Starts asynchronous initialization of the object implementing the
 * interface. This must be done before any real use of the object after
 * initial construction. If the object also implements #GInitable you can
 * optionally call g_initable_init() instead.
 *
 * When the initialization is finished, @callback will be called. You can
 * then call g_async_initable_init_finish() to get the result of the
 * initialization.
 *
 * Implementations may also support cancellation. If @cancellable is not
 * %NULL, then initialization can be cancelled by triggering the cancellable
 * object from another thread. If the operation was cancelled, the error
 * %G_IO_ERROR_CANCELLED will be returned. If @cancellable is not %NULL, and
 * the object doesn't support cancellable initialization, the error
 * %G_IO_ERROR_NOT_SUPPORTED will be returned.
 *
 * If this function is not called, or returns with an error, then all
 * operations on the object should fail, generally returning the
 * error %G_IO_ERROR_NOT_INITIALIZED.
 *
 * Implementations of this method must be idempotent: i.e. multiple calls
 * to this function with the same argument should return the same results.
 * Only the first call initializes the object; further calls return the result
 * of the first call. This is so that it's safe to implement the singleton
 * pattern in the GObject constructor function.
 *
 * For classes that also support the #GInitable interface, the default
 * implementation of this method will run the g_initable_init() function
 * in a thread, so if you want to support asynchronous initialization via
 * threads, just implement the #GAsyncInitable interface without overriding
 * any interface methods.
 *
 * Since: 2.22
 */
void
g_async_initable_init_async (GAsyncInitable      *initable,
			     int                  io_priority,
			     GCancellable        *cancellable,
			     GAsyncReadyCallback  callback,
			     gpointer             user_data)
{
  GAsyncInitableIface *iface;

  g_return_if_fail (G_IS_ASYNC_INITABLE (initable));

  iface = G_ASYNC_INITABLE_GET_IFACE (initable);

  (* iface->init_async) (initable, io_priority, cancellable, callback, user_data);
}

/**
 * g_async_initable_init_finish:
 * @initable: a #GAsyncInitable.
 * @res: a #GAsyncResult.
 * @error: a #GError location to store the error occurring, or %NULL to
 * ignore.
 *
 * Finishes asynchronous initialization and returns the result.
 * See g_async_initable_init_async().
 *
 * Returns: %TRUE if successful. If an error has occurred, this function
 * will return %FALSE and set @error appropriately if present.
 *
 * Since: 2.22
 */
gboolean
g_async_initable_init_finish (GAsyncInitable  *initable,
			      GAsyncResult    *res,
			      GError         **error)
{
  GAsyncInitableIface *iface;

  g_return_val_if_fail (G_IS_ASYNC_INITABLE (initable), FALSE);
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);

  if (G_IS_SIMPLE_ASYNC_RESULT (res))
    {
      GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
      if (g_simple_async_result_propagate_error (simple, error))
	return FALSE;
    }

  iface = G_ASYNC_INITABLE_GET_IFACE (initable);

  return (* iface->init_finish) (initable, res, error);
}

static void
async_init_thread (GSimpleAsyncResult *res,
		   GObject            *object,
		   GCancellable       *cancellable)
{
  GError *error = NULL;

  if (!g_initable_init (G_INITABLE (object), cancellable, &error))
    g_simple_async_result_take_error (res, error);
}

static void
g_async_initable_real_init_async (GAsyncInitable      *initable,
				  int                  io_priority,
				  GCancellable        *cancellable,
				  GAsyncReadyCallback  callback,
				  gpointer             user_data)
{
  GSimpleAsyncResult *res;

  g_return_if_fail (G_IS_INITABLE (initable));

  res = g_simple_async_result_new (G_OBJECT (initable), callback, user_data,
				   g_async_initable_real_init_async);
  g_simple_async_result_run_in_thread (res, async_init_thread,
				       io_priority, cancellable);
  g_object_unref (res);
}

static gboolean
g_async_initable_real_init_finish (GAsyncInitable  *initable,
				   GAsyncResult    *res,
				   GError         **error)
{
  return TRUE; /* Errors handled by base impl */
}

/**
 * g_async_initable_new_async:
 * @object_type: a #GType supporting #GAsyncInitable.
 * @io_priority: the <link linkend="io-priority">I/O priority</link>
 *     of the operation.
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 * @callback: a #GAsyncReadyCallback to call when the initialization is
 *     finished
 * @user_data: the data to pass to callback function
 * @first_property_name: the name of the first property, or %NULL if no
 *     properties
 * @...:  the value of the first property, followed by other property
 *    value pairs, and ended by %NULL.
 *
 * Helper function for constructing #GAsyncInitable object. This is
 * similar to g_object_new() but also initializes the object asynchronously.
 *
 * When the initialization is finished, @callback will be called. You can
 * then call g_async_initable_new_finish() to get the new object and check
 * for any errors.
 *
 * Since: 2.22
 */
void
g_async_initable_new_async (GType                object_type,
			    int                  io_priority,
			    GCancellable        *cancellable,
			    GAsyncReadyCallback  callback,
			    gpointer             user_data,
			    const gchar         *first_property_name,
			    ...)
{
  va_list var_args;

  va_start (var_args, first_property_name);
  g_async_initable_new_valist_async (object_type,
				     first_property_name, var_args,
				     io_priority, cancellable,
				     callback, user_data);
  va_end (var_args);
}

/**
 * g_async_initable_newv_async:
 * @object_type: a #GType supporting #GAsyncInitable.
 * @n_parameters: the number of parameters in @parameters
 * @parameters: the parameters to use to construct the object
 * @io_priority: the <link linkend="io-priority">I/O priority</link>
 *     of the operation.
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 * @callback: a #GAsyncReadyCallback to call when the initialization is
 *     finished
 * @user_data: the data to pass to callback function
 *
 * Helper function for constructing #GAsyncInitable object. This is
 * similar to g_object_newv() but also initializes the object asynchronously.
 *
 * When the initialization is finished, @callback will be called. You can
 * then call g_async_initable_new_finish() to get the new object and check
 * for any errors.
 *
 * Since: 2.22
 */
void
g_async_initable_newv_async (GType                object_type,
			     guint                n_parameters,
			     GParameter          *parameters,
			     int                  io_priority,
			     GCancellable        *cancellable,
			     GAsyncReadyCallback  callback,
			     gpointer             user_data)
{
  GObject *obj;

  g_return_if_fail (G_TYPE_IS_ASYNC_INITABLE (object_type));

  obj = g_object_newv (object_type, n_parameters, parameters);

  g_async_initable_init_async (G_ASYNC_INITABLE (obj),
			       io_priority, cancellable,
			       callback, user_data);
}

/**
 * g_async_initable_new_valist_async:
 * @object_type: a #GType supporting #GAsyncInitable.
 * @first_property_name: the name of the first property, followed by
 * the value, and other property value pairs, and ended by %NULL.
 * @var_args: The var args list generated from @first_property_name.
 * @io_priority: the <link linkend="io-priority">I/O priority</link>
 *     of the operation.
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 * @callback: a #GAsyncReadyCallback to call when the initialization is
 *     finished
 * @user_data: the data to pass to callback function
 *
 * Helper function for constructing #GAsyncInitable object. This is
 * similar to g_object_new_valist() but also initializes the object
 * asynchronously.
 *
 * When the initialization is finished, @callback will be called. You can
 * then call g_async_initable_new_finish() to get the new object and check
 * for any errors.
 *
 * Since: 2.22
 */
void
g_async_initable_new_valist_async (GType                object_type,
				   const gchar         *first_property_name,
				   va_list              var_args,
				   int                  io_priority,
				   GCancellable        *cancellable,
				   GAsyncReadyCallback  callback,
				   gpointer             user_data)
{
  GObject *obj;

  g_return_if_fail (G_TYPE_IS_ASYNC_INITABLE (object_type));

  obj = g_object_new_valist (object_type,
			     first_property_name,
			     var_args);

  g_async_initable_init_async (G_ASYNC_INITABLE (obj),
			       io_priority, cancellable,
			       callback, user_data);
  g_object_unref (obj); /* Passed ownership to async call */
}

/**
 * g_async_initable_new_finish:
 * @initable: the #GAsyncInitable from the callback
 * @res: the #GAsyncResult from the callback
 * @error: return location for errors, or %NULL to ignore
 *
 * Finishes the async construction for the various g_async_initable_new
 * calls, returning the created object or %NULL on error.
 *
 * Returns: (transfer full): a newly created #GObject, or %NULL on error.
 *     Free with g_object_unref().
 *
 * Since: 2.22
 */
GObject *
g_async_initable_new_finish (GAsyncInitable  *initable,
			     GAsyncResult    *res,
			     GError         **error)
{
  if (g_async_initable_init_finish (initable, res, error))
    return g_object_ref (initable);
  else
    return NULL;
}
