/* GStreamer plugin for forward error correction
 * Copyright (C) 2017 Pexip
 *
 * 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Author: Mikhail Fludkov <misha@pexip.com>
 */

#include <string.h>
#include "rtpulpfeccommon.h"

#define MIN_RTP_HEADER_LEN 12

typedef struct
{
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
  unsigned int csrc_count:4;    /* CSRC count */
  unsigned int extension:1;     /* header extension flag */
  unsigned int padding:1;       /* padding flag */
  unsigned int version:2;       /* protocol version */
  unsigned int payload_type:7;  /* payload type */
  unsigned int marker:1;        /* marker bit */
#elif G_BYTE_ORDER == G_BIG_ENDIAN
  unsigned int version:2;       /* protocol version */
  unsigned int padding:1;       /* padding flag */
  unsigned int extension:1;     /* header extension flag */
  unsigned int csrc_count:4;    /* CSRC count */
  unsigned int marker:1;        /* marker bit */
  unsigned int payload_type:7;  /* payload type */
#else
#error "G_BYTE_ORDER should be big or little endian."
#endif
  unsigned int seq:16;          /* sequence number */
  unsigned int timestamp:32;    /* timestamp */
  unsigned int ssrc:32;         /* synchronization source */
  guint8 csrclist[4];           /* optional CSRC list, 32 bits each */
} RtpHeader;

static gsize
fec_level_hdr_get_size (gboolean l_bit)
{
  return sizeof (RtpUlpFecLevelHeader) - (l_bit ? 0 : 4);
}

static guint64
fec_level_hdr_get_mask (RtpUlpFecLevelHeader const *fec_lvl_hdr, gboolean l_bit)
{
  return ((guint64) g_ntohs (fec_lvl_hdr->mask) << 32) |
      (l_bit ? g_ntohl (fec_lvl_hdr->mask_continued) : 0);
}

static void
fec_level_hdr_set_mask (RtpUlpFecLevelHeader * fec_lvl_hdr, gboolean l_bit,
    guint64 mask)
{
  fec_lvl_hdr->mask = g_htons (mask >> 32);
  if (l_bit)
    fec_lvl_hdr->mask_continued = g_htonl (mask);
}

static guint16
fec_level_hdr_get_protection_len (RtpUlpFecLevelHeader * fec_lvl_hdr)
{
  return g_ntohs (fec_lvl_hdr->protection_len);
}

static void
fec_level_hdr_set_protection_len (RtpUlpFecLevelHeader * fec_lvl_hdr,
    guint16 len)
{
  fec_lvl_hdr->protection_len = g_htons (len);
}

static RtpUlpFecLevelHeader *
fec_hdr_get_level_hdr (RtpUlpFecHeader const *fec_hdr)
{
  return (RtpUlpFecLevelHeader *) (fec_hdr + 1);
}

static guint64
fec_hdr_get_mask (RtpUlpFecHeader const *fec_hdr)
{
  return fec_level_hdr_get_mask (fec_hdr_get_level_hdr (fec_hdr), fec_hdr->L);
}

static guint16
fec_hdr_get_seq_base (RtpUlpFecHeader const *fec_hdr, gboolean is_ulpfec,
    guint16 fec_seq)
{
  guint16 seq = g_ntohs (fec_hdr->seq);
  if (is_ulpfec)
    return seq;
  return fec_seq - seq;
}

static guint16
fec_hdr_get_packets_len_recovery (RtpUlpFecHeader const *fec_hdr)
{
  return g_htons (fec_hdr->len);
}

static guint32
fec_hdr_get_timestamp_recovery (RtpUlpFecHeader const *fec_hdr)
{
  return g_ntohl (fec_hdr->timestamp);
}

static void
_xor_mem (guint8 * restrict dst, const guint8 * restrict src, gsize length)
{
  guint i;

  for (i = 0; i < (length / sizeof (guint64)); ++i) {
    *((guint64 *) dst) ^= *((const guint64 *) src);
    dst += sizeof (guint64);
    src += sizeof (guint64);
  }
  for (i = 0; i < (length % sizeof (guint64)); ++i)
    dst[i] ^= src[i];
}

guint16
rtp_ulpfec_hdr_get_protection_len (RtpUlpFecHeader const *fec_hdr)
{
  return fec_level_hdr_get_protection_len (fec_hdr_get_level_hdr (fec_hdr));
}

RtpUlpFecHeader *
rtp_ulpfec_buffer_get_fechdr (GstRTPBuffer * rtp)
{
  return (RtpUlpFecHeader *) gst_rtp_buffer_get_payload (rtp);
}

guint64
rtp_ulpfec_buffer_get_mask (GstRTPBuffer * rtp)
{
  return fec_hdr_get_mask (rtp_ulpfec_buffer_get_fechdr (rtp));
}

guint16
rtp_ulpfec_buffer_get_seq_base (GstRTPBuffer * rtp)
{
  return g_ntohs (rtp_ulpfec_buffer_get_fechdr (rtp)->seq);
}

guint
rtp_ulpfec_get_headers_len (gboolean fec_mask_long)
{
  return sizeof (RtpUlpFecHeader) + fec_level_hdr_get_size (fec_mask_long);
}

#define ONE_64BIT G_GUINT64_CONSTANT(1)

guint64
rtp_ulpfec_packet_mask_from_seqnum (guint16 seq,
    guint16 fec_seq_base, gboolean fec_mask_long)
{
  gint seq_delta = gst_rtp_buffer_compare_seqnum (fec_seq_base, seq);
  if (seq_delta >= 0
      && seq_delta <= RTP_ULPFEC_SEQ_BASE_OFFSET_MAX (fec_mask_long)) {
    return ONE_64BIT << (RTP_ULPFEC_SEQ_BASE_OFFSET_MAX (TRUE) - seq_delta);
  }
  return 0;
}

gboolean
rtp_ulpfec_mask_is_long (guint64 mask)
{
  return (mask & 0xffffffff) ? TRUE : FALSE;
}

gboolean
rtp_ulpfec_buffer_is_valid (GstRTPBuffer * rtp)
{
  guint payload_len = gst_rtp_buffer_get_payload_len (rtp);
  RtpUlpFecHeader *fec_hdr;
  guint fec_hdrs_len;
  guint fec_packet_len;

  if (payload_len < sizeof (RtpUlpFecHeader))
    goto toosmall;

  fec_hdr = rtp_ulpfec_buffer_get_fechdr (rtp);
  if (fec_hdr->E)
    goto invalidcontent;

  fec_hdrs_len = rtp_ulpfec_get_headers_len (fec_hdr->L);
  if (payload_len < fec_hdrs_len)
    goto toosmall;

  fec_packet_len = fec_hdrs_len + rtp_ulpfec_hdr_get_protection_len (fec_hdr);
  if (fec_packet_len != payload_len)
    goto lengthmismatch;

  return TRUE;
toosmall:
  GST_WARNING ("FEC packet too small");
  return FALSE;

lengthmismatch:
  GST_WARNING ("invalid FEC packet (declared length %u, real length %u)",
      fec_packet_len, payload_len);
  return FALSE;

invalidcontent:
  GST_WARNING ("FEC Header contains invalid fields: %u", fec_hdr->E);
  return FALSE;
}


void
rtp_buffer_to_ulpfec_bitstring (GstRTPBuffer * rtp, GArray * dst_arr,
    gboolean fec_buffer, gboolean fec_mask_long)
{
  if (G_UNLIKELY (fec_buffer)) {
    guint payload_len = gst_rtp_buffer_get_payload_len (rtp);
    g_array_set_size (dst_arr, MAX (payload_len, dst_arr->len));
    memcpy (dst_arr->data, gst_rtp_buffer_get_payload (rtp), payload_len);
  } else {
    const guint8 *src = rtp->data[0];
    guint len = gst_rtp_buffer_get_packet_len (rtp) - MIN_RTP_HEADER_LEN;
    guint dst_offset = rtp_ulpfec_get_headers_len (fec_mask_long);
    guint src_offset = MIN_RTP_HEADER_LEN;
    guint8 *dst;

    g_array_set_size (dst_arr, MAX (dst_offset + len, dst_arr->len));
    dst = (guint8 *) dst_arr->data;

    *((guint64 *) dst) ^= *((const guint64 *) src);
    ((RtpUlpFecHeader *) dst)->len ^= g_htons (len);
    _xor_mem (dst + dst_offset, src + src_offset, len);
  }
}

GstBuffer *
rtp_ulpfec_bitstring_to_media_rtp_buffer (GArray * arr,
    gboolean fec_mask_long, guint32 ssrc, guint16 seq)
{
  guint fec_hdrs_len = rtp_ulpfec_get_headers_len (fec_mask_long);
  guint payload_len =
      fec_hdr_get_packets_len_recovery ((RtpUlpFecHeader *) arr->data);
  GstMapInfo ret_info = GST_MAP_INFO_INIT;
  GstMemory *ret_mem;
  GstBuffer *ret;

  if (payload_len > arr->len - fec_hdrs_len)
    return NULL;                // Not enough data

  ret_mem = gst_allocator_alloc (NULL, MIN_RTP_HEADER_LEN + payload_len, NULL);
  gst_memory_map (ret_mem, &ret_info, GST_MAP_READWRITE);

  /* Filling 12 bytes of RTP header */
  *((guint64 *) ret_info.data) = *((guint64 *) arr->data);
  ((RtpHeader *) ret_info.data)->version = 2;
  ((RtpHeader *) ret_info.data)->seq = g_htons (seq);
  ((RtpHeader *) ret_info.data)->ssrc = g_htonl (ssrc);
  /* Filling payload */
  memcpy (ret_info.data + MIN_RTP_HEADER_LEN,
      arr->data + fec_hdrs_len, payload_len);

  gst_memory_unmap (ret_mem, &ret_info);
  ret = gst_buffer_new ();
  gst_buffer_append_memory (ret, ret_mem);
  return ret;
}

GstBuffer *
rtp_ulpfec_bitstring_to_fec_rtp_buffer (GArray * arr,
    guint16 seq_base, gboolean fec_mask_long, guint64 fec_mask,
    gboolean marker, guint8 pt, guint16 seq, guint32 timestamp, guint32 ssrc)
{
  GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
  GstBuffer *ret;

  /* Filling FEC headers */
  {
    RtpUlpFecHeader *hdr = (RtpUlpFecHeader *) arr->data;
    RtpUlpFecLevelHeader *lvlhdr;
    hdr->E = 0;
    hdr->L = fec_mask_long;
    hdr->seq = g_htons (seq_base);

    lvlhdr = fec_hdr_get_level_hdr (hdr);
    fec_level_hdr_set_protection_len (lvlhdr,
        arr->len - rtp_ulpfec_get_headers_len (fec_mask_long));
    fec_level_hdr_set_mask (lvlhdr, fec_mask_long, fec_mask);
  }

  /* Filling RTP header, copying payload */
  ret = gst_rtp_buffer_new_allocate (arr->len, 0, 0);
  if (!gst_rtp_buffer_map (ret, GST_MAP_READWRITE, &rtp))
    g_assert_not_reached ();

  gst_rtp_buffer_set_marker (&rtp, marker);
  gst_rtp_buffer_set_payload_type (&rtp, pt);
  gst_rtp_buffer_set_seq (&rtp, seq);
  gst_rtp_buffer_set_timestamp (&rtp, timestamp);
  gst_rtp_buffer_set_ssrc (&rtp, ssrc);

  memcpy (gst_rtp_buffer_get_payload (&rtp), arr->data, arr->len);

  gst_rtp_buffer_unmap (&rtp);

  return ret;
}

/**
 * rtp_ulpfec_map_info_map:
 * @buffer: (transfer: full) #GstBuffer
 * @info: #RtpUlpFecMapInfo
 *
 * Maps the contents of @buffer into @info. If @buffer made of many #GstMemory
 * objects, merges them together to create a new buffer made of single
 * continious #GstMemory.
 *
 * Returns: %TRUE if @buffer could be mapped
 **/
gboolean
rtp_ulpfec_map_info_map (GstBuffer * buffer, RtpUlpFecMapInfo * info)
{
  /* We need to make sure we are working with continious memory chunk.
   * If not merge all memories together */
  if (gst_buffer_n_memory (buffer) > 1) {
    GstBuffer *new_buffer = gst_buffer_new ();
    GstMemory *mem = gst_buffer_get_all_memory (buffer);
    gst_buffer_append_memory (new_buffer, mem);

    /* We supposed to own the old buffer, but we don't use it here, so unref */
    gst_buffer_unref (buffer);
    buffer = new_buffer;
  }

  if (!gst_rtp_buffer_map (buffer,
          GST_MAP_READ | GST_RTP_BUFFER_MAP_FLAG_SKIP_PADDING, &info->rtp)) {
    /* info->rtp.buffer = NULL is an indication for rtp_ulpfec_map_info_unmap()
     * that mapping has failed */
    g_assert (NULL == info->rtp.buffer);
    gst_buffer_unref (buffer);
    return FALSE;
  }
  return TRUE;
}

/**
 * rtp_ulpfec_map_info_unmap:
 * @info: #RtpUlpFecMapInfo
 *
 * Unmap @info previously mapped with rtp_ulpfec_map_info_map() and unrefs the
 * buffer. For convinience can even be called even if rtp_ulpfec_map_info_map
 * returned FALSE
 **/
void
rtp_ulpfec_map_info_unmap (RtpUlpFecMapInfo * info)
{
  GstBuffer *buffer = info->rtp.buffer;

  if (buffer) {
    gst_rtp_buffer_unmap (&info->rtp);
    gst_buffer_unref (buffer);
  }
}

#ifndef GST_DISABLE_GST_DEBUG
void
rtp_ulpfec_log_rtppacket (GstDebugCategory * cat, GstDebugLevel level,
    gpointer object, const gchar * name, GstRTPBuffer * rtp)
{
  guint seq;
  guint ssrc;
  guint timestamp;
  guint pt;

  if (level > gst_debug_category_get_threshold (cat))
    return;

  seq = gst_rtp_buffer_get_seq (rtp);
  ssrc = gst_rtp_buffer_get_ssrc (rtp);
  timestamp = gst_rtp_buffer_get_timestamp (rtp);
  pt = gst_rtp_buffer_get_payload_type (rtp);

  GST_CAT_LEVEL_LOG (cat, level, object,
      "%-22s: [%c%c%c%c] ssrc=0x%08x pt=%u tstamp=%u seq=%u size=%u(%u,%u)",
      name,
      gst_rtp_buffer_get_marker (rtp) ? 'M' : ' ',
      gst_rtp_buffer_get_extension (rtp) ? 'X' : ' ',
      gst_rtp_buffer_get_padding (rtp) ? 'P' : ' ',
      gst_rtp_buffer_get_csrc_count (rtp) > 0 ? 'C' : ' ',
      ssrc, pt, timestamp, seq,
      gst_rtp_buffer_get_packet_len (rtp),
      gst_rtp_buffer_get_packet_len (rtp) - MIN_RTP_HEADER_LEN,
      gst_rtp_buffer_get_payload_len (rtp));
}
#endif /* GST_DISABLE_GST_DEBUG */

#ifndef GST_DISABLE_GST_DEBUG
void
rtp_ulpfec_log_fec_packet (GstDebugCategory * cat, GstDebugLevel level,
    gpointer object, GstRTPBuffer * fecrtp)
{
  RtpUlpFecHeader *fec_hdr;
  RtpUlpFecLevelHeader *fec_level_hdr;

  if (level > gst_debug_category_get_threshold (cat))
    return;

  fec_hdr = gst_rtp_buffer_get_payload (fecrtp);
  GST_CAT_LEVEL_LOG (cat, level, object,
      "%-22s: [%c%c%c%c%c%c] pt=%u tstamp=%u seq=%u recovery_len=%u",
      "fec header",
      fec_hdr->E ? 'E' : ' ',
      fec_hdr->L ? 'L' : ' ',
      fec_hdr->P ? 'P' : ' ',
      fec_hdr->X ? 'X' : ' ',
      fec_hdr->CC ? 'C' : ' ',
      fec_hdr->M ? 'M' : ' ',
      fec_hdr->pt,
      fec_hdr_get_timestamp_recovery (fec_hdr),
      fec_hdr_get_seq_base (fec_hdr, TRUE,
          gst_rtp_buffer_get_seq (fecrtp)),
      fec_hdr_get_packets_len_recovery (fec_hdr));

  fec_level_hdr = fec_hdr_get_level_hdr (fec_hdr);
  GST_CAT_LEVEL_LOG (cat, level, object,
      "%-22s: protection_len=%u mask=0x%012" G_GINT64_MODIFIER "x",
      "fec level header",
      g_ntohs (fec_level_hdr->protection_len),
      fec_level_hdr_get_mask (fec_level_hdr, fec_hdr->L));
}
#endif /* GST_DISABLE_GST_DEBUG */
