/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *                    2005 Wim Taymans <wim@fluendo.com>
 *                    2005 Andy Wingo <wingo@pobox.com>
 * Copyright (C) 2012 Collabora Ltd. <tim.muller@collabora.co.uk>
 *
 * gstnetclientclock.h: clock that synchronizes itself to a time provider over
 * the network
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library 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.
 */
/**
 * SECTION:gstnetclientclock
 * @short_description: Special clock that synchronizes to a remote time
 *                     provider.
 * @see_also: #GstClock, #GstNetTimeProvider, #GstPipeline
 *
 * This object implements a custom #GstClock that synchronizes its time
 * to a remote time provider such as #GstNetTimeProvider.
 *
 * A new clock is created with gst_net_client_clock_new() which takes the
 * address and port of the remote time provider along with a name and
 * an initial time.
 *
 * This clock will poll the time provider and will update its calibration
 * parameters based on the local and remote observations.
 *
 * Various parameters of the clock can be configured with the parent #GstClock
 * "timeout", "window-size" and "window-threshold" object properties.
 *
 * A #GstNetClientClock is typically set on a #GstPipeline with 
 * gst_pipeline_use_clock().
 *
 * Last reviewed on 2005-11-23 (0.9.5)
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "gstnettimepacket.h"
#include "gstnetclientclock.h"

#include <gio/gio.h>

GST_DEBUG_CATEGORY_STATIC (ncc_debug);
#define GST_CAT_DEFAULT (ncc_debug)

#define DEFAULT_ADDRESS         "127.0.0.1"
#define DEFAULT_PORT            5637
#define DEFAULT_TIMEOUT         GST_SECOND

enum
{
  PROP_0,
  PROP_ADDRESS,
  PROP_PORT
};

#define GST_NET_CLIENT_CLOCK_GET_PRIVATE(obj)  \
  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_NET_CLIENT_CLOCK, GstNetClientClockPrivate))

struct _GstNetClientClockPrivate
{
  GThread *thread;

  GSocket *socket;
  GSocketAddress *servaddr;
  GCancellable *cancel;

  GstClockTime timeout_expiration;

  gchar *address;
  gint port;
};

#define _do_init \
  GST_DEBUG_CATEGORY_INIT (ncc_debug, "netclock", 0, "Network client clock");
#define gst_net_client_clock_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstNetClientClock, gst_net_client_clock,
    GST_TYPE_SYSTEM_CLOCK, _do_init);

static void gst_net_client_clock_finalize (GObject * object);
static void gst_net_client_clock_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_net_client_clock_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static void gst_net_client_clock_stop (GstNetClientClock * self);

static void
gst_net_client_clock_class_init (GstNetClientClockClass * klass)
{
  GObjectClass *gobject_class;

  gobject_class = G_OBJECT_CLASS (klass);

  g_type_class_add_private (klass, sizeof (GstNetClientClockPrivate));

  gobject_class->finalize = gst_net_client_clock_finalize;
  gobject_class->get_property = gst_net_client_clock_get_property;
  gobject_class->set_property = gst_net_client_clock_set_property;

  g_object_class_install_property (gobject_class, PROP_ADDRESS,
      g_param_spec_string ("address", "address",
          "The IP address of the machine providing a time server",
          DEFAULT_ADDRESS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_PORT,
      g_param_spec_int ("port", "port",
          "The port on which the remote server is listening", 0, G_MAXUINT16,
          DEFAULT_PORT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}

static void
gst_net_client_clock_init (GstNetClientClock * self)
{
  GstClock *clock = GST_CLOCK_CAST (self);
  GstNetClientClockPrivate *priv;

  self->priv = priv = GST_NET_CLIENT_CLOCK_GET_PRIVATE (self);

  priv->port = DEFAULT_PORT;
  priv->address = g_strdup (DEFAULT_ADDRESS);

  gst_clock_set_timeout (clock, DEFAULT_TIMEOUT);

  priv->thread = NULL;

  priv->servaddr = NULL;
}

static void
gst_net_client_clock_finalize (GObject * object)
{
  GstNetClientClock *self = GST_NET_CLIENT_CLOCK (object);

  if (self->priv->thread) {
    gst_net_client_clock_stop (self);
  }

  g_free (self->priv->address);
  self->priv->address = NULL;

  if (self->priv->servaddr != NULL) {
    g_object_unref (self->priv->servaddr);
    self->priv->servaddr = NULL;
  }

  if (self->priv->socket != NULL) {
    g_socket_close (self->priv->socket, NULL);
    g_object_unref (self->priv->socket);
    self->priv->socket = NULL;
  }

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

static void
gst_net_client_clock_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstNetClientClock *self = GST_NET_CLIENT_CLOCK (object);

  switch (prop_id) {
    case PROP_ADDRESS:
      g_free (self->priv->address);
      self->priv->address = g_value_dup_string (value);
      if (self->priv->address == NULL)
        self->priv->address = g_strdup (DEFAULT_ADDRESS);
      break;
    case PROP_PORT:
      self->priv->port = g_value_get_int (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_net_client_clock_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstNetClientClock *self = GST_NET_CLIENT_CLOCK (object);

  switch (prop_id) {
    case PROP_ADDRESS:
      g_value_set_string (value, self->priv->address);
      break;
    case PROP_PORT:
      g_value_set_int (value, self->priv->port);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_net_client_clock_observe_times (GstNetClientClock * self,
    GstClockTime local_1, GstClockTime remote, GstClockTime local_2)
{
  GstClockTime current_timeout;
  GstClockTime local_avg;
  gdouble r_squared;
  GstClock *clock;

  if (local_2 < local_1)
    goto bogus_observation;

  local_avg = (local_2 + local_1) / 2;

  clock = GST_CLOCK_CAST (self);

  if (gst_clock_add_observation (GST_CLOCK (self), local_avg, remote,
          &r_squared)) {
    /* geto formula */
    current_timeout = (1e-3 / (1 - MIN (r_squared, 0.99999))) * GST_SECOND;
    current_timeout = MIN (current_timeout, gst_clock_get_timeout (clock));
  } else {
    current_timeout = 0;
  }

  GST_INFO ("next timeout: %" GST_TIME_FORMAT, GST_TIME_ARGS (current_timeout));
  self->priv->timeout_expiration = gst_util_get_timestamp () + current_timeout;

  return;

bogus_observation:
  {
    GST_WARNING_OBJECT (self, "time packet receive time < send time (%"
        GST_TIME_FORMAT " < %" GST_TIME_FORMAT ")", GST_TIME_ARGS (local_1),
        GST_TIME_ARGS (local_2));
    return;
  }
}

typedef struct
{
  GSource source;
  GstNetClientClock *clock;
  gboolean *p_timeout;
} GstNetClientClockTimeoutSource;

static gboolean
gst_net_client_clock_timeout_source_prepare (GSource * s, gint * p_timeout)
{
  GstNetClientClockTimeoutSource *source = (GstNetClientClockTimeoutSource *) s;
  GstClockTime expiration_time = source->clock->priv->timeout_expiration;
  GstClockTime now = gst_util_get_timestamp ();

  if (now >= expiration_time || (expiration_time - now) <= GST_MSECOND) {
    *p_timeout = 0;
    return TRUE;
  }

  *p_timeout = (expiration_time - now) / GST_MSECOND;
  GST_TRACE_OBJECT (source->clock, "time out in %d ms please", *p_timeout);
  return FALSE;
}

static gboolean
gst_net_client_clock_timeout_source_check (GSource * s)
{
  GstNetClientClockTimeoutSource *source = (GstNetClientClockTimeoutSource *) s;

  return (gst_util_get_timestamp () >= source->clock->priv->timeout_expiration);
}

static gboolean
gst_net_client_clock_timeout_source_dispatch (GSource * s, GSourceFunc cb,
    gpointer data)
{
  GstNetClientClockTimeoutSource *source = (GstNetClientClockTimeoutSource *) s;

  GST_TRACE_OBJECT (source->clock, "timed out");
  *source->p_timeout = TRUE;
  return TRUE;
}

static gboolean
gst_net_client_clock_socket_cb (GSocket * socket, GIOCondition condition,
    gpointer user_data)
{
  GIOCondition *p_cond = user_data;

  GST_TRACE ("socket %p I/O condition: 0x%02x", socket, condition);
  *p_cond = condition;
  return TRUE;
}

static gpointer
gst_net_client_clock_thread (gpointer data)
{
  GstNetClientClock *self = data;
  GstNetTimePacket *packet;
  GMainContext *ctx;
  GSourceFuncs funcs = { NULL, };
  GSource *source;
  GIOCondition cond;
  gboolean timeout;
  GSocket *socket = self->priv->socket;
  GError *err = NULL;
  GstClock *clock = data;

  GST_INFO_OBJECT (self, "net client clock thread running, socket=%p", socket);

  g_socket_set_blocking (socket, TRUE);
  g_socket_set_timeout (socket, 0);

  ctx = g_main_context_new ();

  source = g_socket_create_source (socket, G_IO_IN, self->priv->cancel);
  g_source_set_name (source, "GStreamer net client clock thread socket");
  g_source_set_callback (source, (GSourceFunc) gst_net_client_clock_socket_cb,
      &cond, NULL);
  g_source_attach (source, ctx);
  g_source_unref (source);

  /* GSocket only support second granularity for timeouts, so roll our own
   * timeout source (so we don't have to create a new source whenever the
   * timeout changes, as we would have to do with the default timeout source) */
  funcs.prepare = gst_net_client_clock_timeout_source_prepare;
  funcs.check = gst_net_client_clock_timeout_source_check;
  funcs.dispatch = gst_net_client_clock_timeout_source_dispatch;
  funcs.finalize = NULL;
  source = g_source_new (&funcs, sizeof (GstNetClientClockTimeoutSource));
  ((GstNetClientClockTimeoutSource *) source)->clock = self;
  ((GstNetClientClockTimeoutSource *) source)->p_timeout = &timeout;
  g_source_set_name (source, "GStreamer net client clock timeout");
  g_source_attach (source, ctx);
  g_source_unref (source);

  while (!g_cancellable_is_cancelled (self->priv->cancel)) {
    cond = 0;
    timeout = FALSE;
    g_main_context_iteration (ctx, TRUE);

    if (g_cancellable_is_cancelled (self->priv->cancel))
      break;

    if (timeout) {
      /* timed out, let's send another packet */
      GST_DEBUG_OBJECT (self, "timed out");

      packet = gst_net_time_packet_new (NULL);

      packet->local_time = gst_clock_get_internal_time (GST_CLOCK (self));

      GST_DEBUG_OBJECT (self, "sending packet, local time = %" GST_TIME_FORMAT,
          GST_TIME_ARGS (packet->local_time));

      gst_net_time_packet_send (packet, self->priv->socket,
          self->priv->servaddr, NULL);

      g_free (packet);

      /* reset timeout (but are expecting a response sooner anyway) */
      self->priv->timeout_expiration =
          gst_util_get_timestamp () + gst_clock_get_timeout (clock);
      continue;
    }

    /* got data to read? */
    if ((cond & G_IO_IN)) {
      GstClockTime new_local;

      new_local = gst_clock_get_internal_time (GST_CLOCK (self));

      packet = gst_net_time_packet_receive (socket, NULL, &err);

      if (err != NULL) {
        GST_WARNING_OBJECT (self, "receive error: %s", err->message);
        g_error_free (err);
        err = NULL;
        continue;
      }

      GST_LOG_OBJECT (self, "got packet back");
      GST_LOG_OBJECT (self, "local_1 = %" GST_TIME_FORMAT,
          GST_TIME_ARGS (packet->local_time));
      GST_LOG_OBJECT (self, "remote = %" GST_TIME_FORMAT,
          GST_TIME_ARGS (packet->remote_time));
      GST_LOG_OBJECT (self, "local_2 = %" GST_TIME_FORMAT,
          GST_TIME_ARGS (new_local));

      /* observe_times will reset the timeout */
      gst_net_client_clock_observe_times (self, packet->local_time,
          packet->remote_time, new_local);

      g_free (packet);
      continue;
    }

    if ((cond & (G_IO_ERR | G_IO_HUP))) {
      GST_DEBUG_OBJECT (self, "socket error?! %s", g_strerror (errno));
      g_usleep (G_USEC_PER_SEC / 10);
      continue;
    }
  }

  GST_INFO_OBJECT (self, "shutting down net client clock thread");
  g_main_context_unref (ctx);
  return NULL;
}

static gboolean
gst_net_client_clock_start (GstNetClientClock * self)
{
  GSocketAddress *servaddr;
  GSocketAddress *myaddr;
  GInetAddress *inetaddr;
  GSocket *socket;
  GError *error = NULL;

  g_return_val_if_fail (self->priv->address != NULL, FALSE);
  g_return_val_if_fail (self->priv->servaddr == NULL, FALSE);

  socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM,
      G_SOCKET_PROTOCOL_UDP, &error);

  if (socket == NULL)
    goto no_socket;

  /* check address we're bound to, mostly for debugging purposes */
  myaddr = g_socket_get_local_address (socket, &error);

  if (myaddr == NULL)
    goto getsockname_error;

  GST_DEBUG_OBJECT (self, "socket opened on UDP port %hd",
      g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (myaddr)));

  g_object_unref (myaddr);

  /* create target address */
  inetaddr = g_inet_address_new_from_string (self->priv->address);

  if (inetaddr == NULL)
    goto bad_address;

  servaddr = g_inet_socket_address_new (inetaddr, self->priv->port);
  g_object_unref (inetaddr);

  g_assert (servaddr != NULL);

  GST_DEBUG_OBJECT (self, "will communicate with %s:%d", self->priv->address,
      self->priv->port);

  self->priv->cancel = g_cancellable_new ();
  self->priv->socket = socket;
  self->priv->servaddr = G_SOCKET_ADDRESS (servaddr);

  self->priv->thread = g_thread_try_new ("GstNetClientClock",
      gst_net_client_clock_thread, self, &error);

  if (error != NULL)
    goto no_thread;

  return TRUE;

  /* ERRORS */
no_socket:
  {
    GST_ERROR_OBJECT (self, "socket_new() failed: %s", error->message);
    g_error_free (error);
    return FALSE;
  }
getsockname_error:
  {
    GST_ERROR_OBJECT (self, "get_local_address() failed: %s", error->message);
    g_error_free (error);
    g_object_unref (socket);
    return FALSE;
  }
bad_address:
  {
    GST_ERROR_OBJECT (self, "inet_address_new_from_string('%s') failed",
        self->priv->address);
    g_object_unref (socket);
    return FALSE;
  }
no_thread:
  {
    GST_ERROR_OBJECT (self, "could not create thread: %s", error->message);
    g_object_unref (self->priv->servaddr);
    self->priv->servaddr = NULL;
    g_object_unref (self->priv->socket);
    self->priv->socket = NULL;
    g_error_free (error);
    return FALSE;
  }
}

static void
gst_net_client_clock_stop (GstNetClientClock * self)
{
  if (self->priv->thread == NULL)
    return;

  GST_INFO_OBJECT (self, "stopping...");
  g_cancellable_cancel (self->priv->cancel);

  g_thread_join (self->priv->thread);
  self->priv->thread = NULL;

  g_object_unref (self->priv->cancel);
  self->priv->cancel = NULL;

  g_object_unref (self->priv->servaddr);
  self->priv->servaddr = NULL;

  g_object_unref (self->priv->socket);
  self->priv->socket = NULL;

  GST_INFO_OBJECT (self, "stopped");
}

/**
 * gst_net_client_clock_new:
 * @name: a name for the clock
 * @remote_address: the address of the remote clock provider
 * @remote_port: the port of the remote clock provider
 * @base_time: initial time of the clock
 *
 * Create a new #GstNetClientClock that will report the time
 * provided by the #GstNetTimeProvider on @remote_address and 
 * @remote_port.
 *
 * Returns: a new #GstClock that receives a time from the remote
 * clock.
 */
GstClock *
gst_net_client_clock_new (gchar * name, const gchar * remote_address,
    gint remote_port, GstClockTime base_time)
{
  /* FIXME: gst_net_client_clock_new() should be a thin wrapper for g_object_new() */
  GstNetClientClock *ret;
  GstClockTime internal;

  g_return_val_if_fail (remote_address != NULL, NULL);
  g_return_val_if_fail (remote_port > 0, NULL);
  g_return_val_if_fail (remote_port <= G_MAXUINT16, NULL);
  g_return_val_if_fail (base_time != GST_CLOCK_TIME_NONE, NULL);

  ret = g_object_new (GST_TYPE_NET_CLIENT_CLOCK, "address", remote_address,
      "port", remote_port, NULL);

  /* gst_clock_get_time() values are guaranteed to be increasing. because no one
   * has called get_time on this clock yet we are free to adjust to any value
   * without worrying about worrying about MAX() issues with the clock's
   * internal time.
   */

  /* update our internal time so get_time() give something around base_time.
     assume that the rate is 1 in the beginning. */
  internal = gst_clock_get_internal_time (GST_CLOCK (ret));
  gst_clock_set_calibration (GST_CLOCK (ret), internal, base_time, 1, 1);

  {
    GstClockTime now = gst_clock_get_time (GST_CLOCK (ret));

    if (GST_CLOCK_DIFF (now, base_time) > 0 ||
        GST_CLOCK_DIFF (now, base_time + GST_SECOND) < 0) {
      g_warning ("unable to set the base time, expect sync problems!");
    }
  }

  if (!gst_net_client_clock_start (ret))
    goto failed_start;

  /* all systems go, cap'n */
  return (GstClock *) ret;

failed_start:
  {
    /* already printed a nice error */
    gst_object_unref (ret);
    return NULL;
  }
}
