/* GStreamer
 * Copyright (C) <2007> Wim Taymans <wim.taymans@gmail.com>
 * Copyright (C)  2015 Kurento (http://kurento.org/)
 *   @author: Miguel París <mparisdiaz@gmail.com>
 *
 * 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., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "rtpstats.h"

void
gst_rtp_packet_rate_ctx_reset (RTPPacketRateCtx * ctx, guint32 clock_rate)
{
  ctx->clock_rate = clock_rate;
  ctx->probed = FALSE;
  ctx->avg_packet_rate = -1;
  ctx->last_ts = -1;
}

guint32
gst_rtp_packet_rate_ctx_update (RTPPacketRateCtx * ctx, guint16 seqnum,
    guint32 ts)
{
  guint64 new_ts, diff_ts;
  gint diff_seqnum;
  guint32 new_packet_rate;

  if (ctx->clock_rate <= 0) {
    return ctx->avg_packet_rate;
  }

  new_ts = ctx->last_ts;
  gst_rtp_buffer_ext_timestamp (&new_ts, ts);

  if (!ctx->probed) {
    ctx->last_seqnum = seqnum;
    ctx->last_ts = new_ts;
    ctx->probed = TRUE;
    return ctx->avg_packet_rate;
  }

  diff_seqnum = gst_rtp_buffer_compare_seqnum (ctx->last_seqnum, seqnum);
  if (diff_seqnum <= 0 || new_ts <= ctx->last_ts) {
    return ctx->avg_packet_rate;
  }

  diff_ts = new_ts - ctx->last_ts;
  diff_ts = gst_util_uint64_scale_int (diff_ts, GST_SECOND, ctx->clock_rate);
  new_packet_rate = gst_util_uint64_scale (diff_seqnum, GST_SECOND, diff_ts);

  /* The goal is that higher packet rates "win".
   * If there's a sudden burst, the average will go up fast,
   * but it will go down again slowly.
   * This is useful for bursty cases, where a lot of packets are close
   * to each other and should allow a higher reorder/dropout there.
   * Round up the new average.
   */
  if (ctx->avg_packet_rate > new_packet_rate) {
    ctx->avg_packet_rate = (7 * ctx->avg_packet_rate + new_packet_rate + 7) / 8;
  } else {
    ctx->avg_packet_rate = (ctx->avg_packet_rate + new_packet_rate + 1) / 2;
  }

  ctx->last_seqnum = seqnum;
  ctx->last_ts = new_ts;

  return ctx->avg_packet_rate;
}

guint32
gst_rtp_packet_rate_ctx_get (RTPPacketRateCtx * ctx)
{
  return ctx->avg_packet_rate;
}

guint32
gst_rtp_packet_rate_ctx_get_max_dropout (RTPPacketRateCtx * ctx, gint32 time_ms)
{
  if (time_ms <= 0 || !ctx->probed) {
    return RTP_DEF_DROPOUT;
  }

  return MAX (RTP_MIN_DROPOUT, ctx->avg_packet_rate * time_ms / 1000);
}

guint32
gst_rtp_packet_rate_ctx_get_max_misorder (RTPPacketRateCtx * ctx,
    gint32 time_ms)
{
  if (time_ms <= 0 || !ctx->probed) {
    return RTP_DEF_MISORDER;
  }

  return MAX (RTP_MIN_MISORDER, ctx->avg_packet_rate * time_ms / 1000);
}

/**
 * rtp_stats_init_defaults:
 * @stats: an #RTPSessionStats struct
 *
 * Initialize @stats with its default values.
 */
void
rtp_stats_init_defaults (RTPSessionStats * stats)
{
  rtp_stats_set_bandwidths (stats, -1, -1, -1, -1);
  stats->min_interval = RTP_STATS_MIN_INTERVAL;
  stats->bye_timeout = RTP_STATS_BYE_TIMEOUT;
  stats->nacks_dropped = 0;
  stats->nacks_sent = 0;
  stats->nacks_received = 0;
}

/**
 * rtp_stats_set_bandwidths:
 * @stats: an #RTPSessionStats struct
 * @rtp_bw: RTP bandwidth
 * @rtcp_bw: RTCP bandwidth
 * @rs: sender RTCP bandwidth
 * @rr: receiver RTCP bandwidth
 *
 * Configure the bandwidth parameters in the stats. When an input variable is
 * set to -1, it will be calculated from the other input variables and from the
 * defaults.
 */
void
rtp_stats_set_bandwidths (RTPSessionStats * stats, guint rtp_bw,
    gdouble rtcp_bw, guint rs, guint rr)
{
  GST_DEBUG ("recalc bandwidths: RTP %u, RTCP %f, RS %u, RR %u", rtp_bw,
      rtcp_bw, rs, rr);

  /* when given, sender and receive bandwidth add up to the total
   * rtcp bandwidth */
  if (rs != -1 && rr != -1)
    rtcp_bw = rs + rr;

  /* If rtcp_bw is between 0 and 1, it is a fraction of rtp_bw */
  if (rtcp_bw > 0.0 && rtcp_bw < 1.0) {
    if (rtp_bw > 0.0)
      rtcp_bw = rtp_bw * rtcp_bw;
    else
      rtcp_bw = -1.0;
  }

  /* RTCP is 5% of the RTP bandwidth */
  if (rtp_bw == -1 && rtcp_bw > 1.0)
    rtp_bw = rtcp_bw * 20;
  else if (rtp_bw != -1 && rtcp_bw < 0.0)
    rtcp_bw = rtp_bw / 20;
  else if (rtp_bw == -1 && rtcp_bw < 0.0) {
    /* nothing given, take defaults */
    rtp_bw = RTP_STATS_BANDWIDTH;
    rtcp_bw = rtp_bw * RTP_STATS_RTCP_FRACTION;
  }

  stats->bandwidth = rtp_bw;
  stats->rtcp_bandwidth = rtcp_bw;

  /* now figure out the fractions */
  if (rs == -1) {
    /* rs unknown */
    if (rr == -1) {
      /* both not given, use defaults */
      rs = stats->rtcp_bandwidth * RTP_STATS_SENDER_FRACTION;
      rr = stats->rtcp_bandwidth * RTP_STATS_RECEIVER_FRACTION;
    } else {
      /* rr known, calculate rs */
      if (stats->rtcp_bandwidth > rr)
        rs = stats->rtcp_bandwidth - rr;
      else
        rs = 0;
    }
  } else if (rr == -1) {
    /* rs known, calculate rr */
    if (stats->rtcp_bandwidth > rs)
      rr = stats->rtcp_bandwidth - rs;
    else
      rr = 0;
  }

  if (stats->rtcp_bandwidth > 0) {
    stats->sender_fraction = ((gdouble) rs) / ((gdouble) stats->rtcp_bandwidth);
    stats->receiver_fraction = 1.0 - stats->sender_fraction;
  } else {
    /* no RTCP bandwidth, set dummy values */
    stats->sender_fraction = 0.0;
    stats->receiver_fraction = 0.0;
  }
  GST_DEBUG ("bandwidths: RTP %u, RTCP %u, RS %f, RR %f", stats->bandwidth,
      stats->rtcp_bandwidth, stats->sender_fraction, stats->receiver_fraction);
}

/**
 * rtp_stats_calculate_rtcp_interval:
 * @stats: an #RTPSessionStats struct
 * @sender: if we are a sender
 * @profile: RTP profile of this session
 * @ptp: if this session is a point-to-point session
 * @first: if this is the first time
 *
 * Calculate the RTCP interval. The result of this function is the amount of
 * time to wait (in nanoseconds) before sending a new RTCP message.
 *
 * Returns: the RTCP interval.
 */
GstClockTime
rtp_stats_calculate_rtcp_interval (RTPSessionStats * stats, gboolean we_send,
    GstRTPProfile profile, gboolean ptp, gboolean first)
{
  gdouble members, senders, n;
  gdouble avg_rtcp_size, rtcp_bw;
  gdouble interval;
  gdouble rtcp_min_time;

  if (profile == GST_RTP_PROFILE_AVPF || profile == GST_RTP_PROFILE_SAVPF) {
    /* RFC 4585 3.4d), 3.5.1 */

    if (first && !ptp)
      rtcp_min_time = 1.0;
    else
      rtcp_min_time = 0.0;
  } else {
    /* Very first call at application start-up uses half the min
     * delay for quicker notification while still allowing some time
     * before reporting for randomization and to learn about other
     * sources so the report interval will converge to the correct
     * interval more quickly.
     */
    rtcp_min_time = stats->min_interval;
    if (first)
      rtcp_min_time /= 2.0;
  }

  /* Dedicate a fraction of the RTCP bandwidth to senders unless
   * the number of senders is large enough that their share is
   * more than that fraction.
   */
  n = members = stats->active_sources;
  senders = (gdouble) stats->sender_sources;
  rtcp_bw = stats->rtcp_bandwidth;

  if (senders <= members * stats->sender_fraction) {
    if (we_send) {
      rtcp_bw *= stats->sender_fraction;
      n = senders;
    } else {
      rtcp_bw *= stats->receiver_fraction;
      n -= senders;
    }
  }

  /* no bandwidth for RTCP, return NONE to signal that we don't want to send
   * RTCP packets */
  if (rtcp_bw <= 0.0001)
    return GST_CLOCK_TIME_NONE;

  avg_rtcp_size = 8.0 * stats->avg_rtcp_packet_size;
  /*
   * The effective number of sites times the average packet size is
   * the total number of octets sent when each site sends a report.
   * Dividing this by the effective bandwidth gives the time
   * interval over which those packets must be sent in order to
   * meet the bandwidth target, with a minimum enforced.  In that
   * time interval we send one report so this time is also our
   * average time between reports.
   */
  GST_DEBUG ("avg size %f, n %f, rtcp_bw %f", avg_rtcp_size, n, rtcp_bw);
  interval = avg_rtcp_size * n / rtcp_bw;
  if (interval < rtcp_min_time)
    interval = rtcp_min_time;

  return interval * GST_SECOND;
}

/**
 * rtp_stats_add_rtcp_jitter:
 * @stats: an #RTPSessionStats struct
 * @interval: an RTCP interval
 *
 * Apply a random jitter to the @interval. @interval is typically obtained with
 * rtp_stats_calculate_rtcp_interval().
 *
 * Returns: the new RTCP interval.
 */
GstClockTime
rtp_stats_add_rtcp_jitter (RTPSessionStats * stats, GstClockTime interval)
{
  gdouble temp;

  /* see RFC 3550 p 30
   * To compensate for "unconditional reconsideration" converging to a
   * value below the intended average.
   */
#define COMPENSATION  (2.71828 - 1.5);

  temp = (interval * g_random_double_range (0.5, 1.5)) / COMPENSATION;

  return (GstClockTime) temp;
}


/**
 * rtp_stats_calculate_bye_interval:
 * @stats: an #RTPSessionStats struct
 *
 * Calculate the BYE interval. The result of this function is the amount of
 * time to wait (in nanoseconds) before sending a BYE message.
 *
 * Returns: the BYE interval.
 */
GstClockTime
rtp_stats_calculate_bye_interval (RTPSessionStats * stats)
{
  gdouble members;
  gdouble avg_rtcp_size, rtcp_bw;
  gdouble interval;
  gdouble rtcp_min_time;

  /* no interval when we have less than 50 members */
  if (stats->active_sources < 50)
    return 0;

  rtcp_min_time = (stats->min_interval) / 2.0;

  /* Dedicate a fraction of the RTCP bandwidth to senders unless
   * the number of senders is large enough that their share is
   * more than that fraction.
   */
  members = stats->bye_members;
  rtcp_bw = stats->rtcp_bandwidth * stats->receiver_fraction;

  /* no bandwidth for RTCP, return NONE to signal that we don't want to send
   * RTCP packets */
  if (rtcp_bw <= 0.0001)
    return GST_CLOCK_TIME_NONE;

  avg_rtcp_size = 8.0 * stats->avg_rtcp_packet_size;
  /*
   * The effective number of sites times the average packet size is
   * the total number of octets sent when each site sends a report.
   * Dividing this by the effective bandwidth gives the time
   * interval over which those packets must be sent in order to
   * meet the bandwidth target, with a minimum enforced.  In that
   * time interval we send one report so this time is also our
   * average time between reports.
   */
  interval = avg_rtcp_size * members / rtcp_bw;
  if (interval < rtcp_min_time)
    interval = rtcp_min_time;

  return interval * GST_SECOND;
}

/**
 * rtp_stats_get_packets_lost:
 * @stats: an #RTPSourceStats struct
 *
 * Calculate the total number of RTP packets lost since beginning of
 * reception. Packets that arrive late are not considered lost, and
 * duplicates are not taken into account. Hence, the loss may be negative
 * if there are duplicates.
 *
 * Returns: total RTP packets lost.
 */
gint64
rtp_stats_get_packets_lost (const RTPSourceStats * stats)
{
  gint64 lost;
  guint64 extended_max, expected;

  extended_max = stats->cycles + stats->max_seq;
  expected = extended_max - stats->base_seq + 1;
  lost = expected - stats->packets_received;

  return lost;
}

void
rtp_stats_set_min_interval (RTPSessionStats * stats, gdouble min_interval)
{
  stats->min_interval = min_interval;
}

gboolean
__g_socket_address_equal (GSocketAddress * a, GSocketAddress * b)
{
  GInetSocketAddress *ia, *ib;
  GInetAddress *iaa, *iab;

  ia = G_INET_SOCKET_ADDRESS (a);
  ib = G_INET_SOCKET_ADDRESS (b);

  if (g_inet_socket_address_get_port (ia) !=
      g_inet_socket_address_get_port (ib))
    return FALSE;

  iaa = g_inet_socket_address_get_address (ia);
  iab = g_inet_socket_address_get_address (ib);

  return g_inet_address_equal (iaa, iab);
}

gchar *
__g_socket_address_to_string (GSocketAddress * addr)
{
  GInetSocketAddress *ia;
  gchar *ret, *tmp;

  ia = G_INET_SOCKET_ADDRESS (addr);

  tmp = g_inet_address_to_string (g_inet_socket_address_get_address (ia));
  ret = g_strdup_printf ("%s:%u", tmp, g_inet_socket_address_get_port (ia));
  g_free (tmp);

  return ret;
}
