/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright © 2009 Codethink Limited
 * Copyright © 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.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/>.
 *
 * Authors: Ryan Lortie <desrt@desrt.ca>
 *          Alexander Larsson <alexl@redhat.com>
 */

/**
 * SECTION:gsocketservice
 * @title: GSocketService
 * @short_description: Make it easy to implement a network service
 * @include: gio/gio.h
 * @see_also: #GThreadedSocketService, #GSocketListener.
 *
 * A #GSocketService is an object that represents a service that
 * is provided to the network or over local sockets.  When a new
 * connection is made to the service the #GSocketService::incoming
 * signal is emitted.
 *
 * A #GSocketService is a subclass of #GSocketListener and you need
 * to add the addresses you want to accept connections on with the
 * #GSocketListener APIs.
 *
 * There are two options for implementing a network service based on
 * #GSocketService. The first is to create the service using
 * g_socket_service_new() and to connect to the #GSocketService::incoming
 * signal. The second is to subclass #GSocketService and override the
 * default signal handler implementation.
 *
 * In either case, the handler must immediately return, or else it
 * will block additional incoming connections from being serviced.
 * If you are interested in writing connection handlers that contain
 * blocking code then see #GThreadedSocketService.
 *
 * The socket service runs on the main loop of the 
 * [thread-default context][g-main-context-push-thread-default-context]
 * of the thread it is created in, and is not
 * threadsafe in general. However, the calls to start and stop the
 * service are thread-safe so these can be used from threads that
 * handle incoming clients.
 *
 * Since: 2.22
 */

#include "config.h"
#include "gsocketservice.h"

#include <gio/gio.h>
#include "gsocketlistener.h"
#include "gsocketconnection.h"
#include "glibintl.h"
#include "gmarshal-internal.h"

struct _GSocketServicePrivate
{
  GCancellable *cancellable;
  guint active : 1;
  guint outstanding_accept : 1;
};

static guint g_socket_service_incoming_signal;

G_LOCK_DEFINE_STATIC(active);

G_DEFINE_TYPE_WITH_PRIVATE (GSocketService, g_socket_service, G_TYPE_SOCKET_LISTENER)

enum
{
  PROP_0,
  PROP_ACTIVE
};

static void g_socket_service_ready (GObject      *object,
				    GAsyncResult *result,
				    gpointer      user_data);

static gboolean
g_socket_service_real_incoming (GSocketService    *service,
                                GSocketConnection *connection,
                                GObject           *source_object)
{
  return FALSE;
}

static void
g_socket_service_init (GSocketService *service)
{
  service->priv = g_socket_service_get_instance_private (service);
  service->priv->cancellable = g_cancellable_new ();
  service->priv->active = TRUE;
}

static void
g_socket_service_finalize (GObject *object)
{
  GSocketService *service = G_SOCKET_SERVICE (object);

  g_object_unref (service->priv->cancellable);

  G_OBJECT_CLASS (g_socket_service_parent_class)
    ->finalize (object);
}

static void
do_accept (GSocketService  *service)
{
  g_socket_listener_accept_async (G_SOCKET_LISTENER (service),
				  service->priv->cancellable,
				  g_socket_service_ready, NULL);
  service->priv->outstanding_accept = TRUE;
}

static gboolean
get_active (GSocketService *service)
{
  gboolean active;

  G_LOCK (active);
  active = service->priv->active;
  G_UNLOCK (active);

  return active;
}

static void
set_active (GSocketService *service, gboolean active)
{
  gboolean notify = FALSE;

  active = !!active;

  G_LOCK (active);

  if (active != service->priv->active)
    {
      service->priv->active = active;
      notify = TRUE;

      if (active)
        {
          if (service->priv->outstanding_accept)
            g_cancellable_cancel (service->priv->cancellable);
          else
            do_accept (service);
        }
      else
        {
          if (service->priv->outstanding_accept)
            g_cancellable_cancel (service->priv->cancellable);
        }
    }

  G_UNLOCK (active);

  if (notify)
    g_object_notify (G_OBJECT (service), "active");
}

static void
g_socket_service_get_property (GObject    *object,
                               guint       prop_id,
                               GValue     *value,
                               GParamSpec *pspec)
{
  GSocketService *service = G_SOCKET_SERVICE (object);

  switch (prop_id)
    {
    case PROP_ACTIVE:
      g_value_set_boolean (value, get_active (service));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
g_socket_service_set_property (GObject      *object,
                               guint         prop_id,
                               const GValue *value,
                               GParamSpec   *pspec)
{
  GSocketService *service = G_SOCKET_SERVICE (object);

  switch (prop_id)
    {
    case PROP_ACTIVE:
      set_active (service, g_value_get_boolean (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
g_socket_service_changed (GSocketListener *listener)
{
  GSocketService  *service = G_SOCKET_SERVICE (listener);

  G_LOCK (active);

  if (service->priv->active)
    {
      if (service->priv->outstanding_accept)
	g_cancellable_cancel (service->priv->cancellable);
      else
	do_accept (service);
    }

  G_UNLOCK (active);
}

/**
 * g_socket_service_is_active:
 * @service: a #GSocketService
 *
 * Check whether the service is active or not. An active
 * service will accept new clients that connect, while
 * a non-active service will let connecting clients queue
 * up until the service is started.
 *
 * Returns: %TRUE if the service is active, %FALSE otherwise
 *
 * Since: 2.22
 */
gboolean
g_socket_service_is_active (GSocketService *service)
{
  g_return_val_if_fail (G_IS_SOCKET_SERVICE (service), FALSE);

  return get_active (service);
}

/**
 * g_socket_service_start:
 * @service: a #GSocketService
 *
 * Restarts the service, i.e. start accepting connections
 * from the added sockets when the mainloop runs. This only needs
 * to be called after the service has been stopped from
 * g_socket_service_stop().
 *
 * This call is thread-safe, so it may be called from a thread
 * handling an incoming client request.
 *
 * Since: 2.22
 */
void
g_socket_service_start (GSocketService *service)
{
  g_return_if_fail (G_IS_SOCKET_SERVICE (service));

  set_active (service, TRUE);
}

/**
 * g_socket_service_stop:
 * @service: a #GSocketService
 *
 * Stops the service, i.e. stops accepting connections
 * from the added sockets when the mainloop runs.
 *
 * This call is thread-safe, so it may be called from a thread
 * handling an incoming client request.
 *
 * Note that this only stops accepting new connections; it does not
 * close the listening sockets, and you can call
 * g_socket_service_start() again later to begin listening again. To
 * close the listening sockets, call g_socket_listener_close(). (This
 * will happen automatically when the #GSocketService is finalized.)
 *
 * This must be called before calling g_socket_listener_close() as
 * the socket service will start accepting connections immediately
 * when a new socket is added.
 *
 * Since: 2.22
 */
void
g_socket_service_stop (GSocketService *service)
{
  g_return_if_fail (G_IS_SOCKET_SERVICE (service));

  set_active (service, FALSE);
}

static gboolean
g_socket_service_incoming (GSocketService    *service,
                           GSocketConnection *connection,
                           GObject           *source_object)
{
  gboolean result;

  g_signal_emit (service, g_socket_service_incoming_signal,
                 0, connection, source_object, &result);
  return result;
}

static void
g_socket_service_class_init (GSocketServiceClass *class)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
  GSocketListenerClass *listener_class = G_SOCKET_LISTENER_CLASS (class);

  gobject_class->finalize = g_socket_service_finalize;
  gobject_class->set_property = g_socket_service_set_property;
  gobject_class->get_property = g_socket_service_get_property;
  listener_class->changed = g_socket_service_changed;
  class->incoming = g_socket_service_real_incoming;

  /**
   * GSocketService::incoming:
   * @service: the #GSocketService
   * @connection: a new #GSocketConnection object
   * @source_object: (nullable): the source_object passed to
   *     g_socket_listener_add_address()
   *
   * The ::incoming signal is emitted when a new incoming connection
   * to @service needs to be handled. The handler must initiate the
   * handling of @connection, but may not block; in essence,
   * asynchronous operations must be used.
   *
   * @connection will be unreffed once the signal handler returns,
   * so you need to ref it yourself if you are planning to use it.
   *
   * Returns: %TRUE to stop other handlers from being called
   *
   * Since: 2.22
   */
  g_socket_service_incoming_signal =
    g_signal_new (I_("incoming"), G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GSocketServiceClass, incoming),
                  g_signal_accumulator_true_handled, NULL,
                  _g_cclosure_marshal_BOOLEAN__OBJECT_OBJECT,
                  G_TYPE_BOOLEAN,
                  2, G_TYPE_SOCKET_CONNECTION, G_TYPE_OBJECT);
  g_signal_set_va_marshaller (g_socket_service_incoming_signal,
                              G_TYPE_FROM_CLASS (class),
                              _g_cclosure_marshal_BOOLEAN__OBJECT_OBJECTv);

  /**
   * GSocketService:active:
   *
   * Whether the service is currently accepting connections.
   *
   * Since: 2.46
   */
  g_object_class_install_property (gobject_class, PROP_ACTIVE,
                                   g_param_spec_boolean ("active",
                                                         P_("Active"),
                                                         P_("Whether the service is currently accepting connections"),
                                                         TRUE,
                                                         G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}

static void
g_socket_service_ready (GObject      *object,
                        GAsyncResult *result,
                        gpointer      user_data)
{
  GSocketListener *listener = G_SOCKET_LISTENER (object);
  GSocketService *service = G_SOCKET_SERVICE (object);
  GSocketConnection *connection;
  GObject *source_object;
  GError *error = NULL;

  connection = g_socket_listener_accept_finish (listener, result, &source_object, &error);
  if (error)
    {
      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
	g_warning ("fail: %s", error->message);
      g_error_free (error);
    }
  else
    {
      g_socket_service_incoming (service, connection, source_object);
      g_object_unref (connection);
    }

  G_LOCK (active);

  g_cancellable_reset (service->priv->cancellable);

  /* requeue */
  service->priv->outstanding_accept = FALSE;
  if (service->priv->active)
    do_accept (service);

  G_UNLOCK (active);
}

/**
 * g_socket_service_new:
 *
 * Creates a new #GSocketService with no sockets to listen for.
 * New listeners can be added with e.g. g_socket_listener_add_address()
 * or g_socket_listener_add_inet_port().
 *
 * New services are created active, there is no need to call
 * g_socket_service_start(), unless g_socket_service_stop() has been
 * called before.
 *
 * Returns: a new #GSocketService.
 *
 * Since: 2.22
 */
GSocketService *
g_socket_service_new (void)
{
  return g_object_new (G_TYPE_SOCKET_SERVICE, NULL);
}
