/* 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);
}

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 1ULL << (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%012lx",
      "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 */
