/*
 * ISO File Format parsing library
 *
 * gstisoff.h
 *
 * Copyright (C) 2015 Samsung Electronics. All rights reserved.
 *   Author: Thiago Santos <thiagoss@osg.samsung.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.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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library (COPYING); if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "gstisoff.h"
#include <gst/base/gstbytereader.h>

#include <string.h>

/* gst_isoff_parse_box:
 * @reader:
 * @type: type that was found at the current position
 * @extended_type: (allow-none): extended type if type=='uuid'
 * @header_size: (allow-none): size of the box header (type, extended type and size)
 * @size: size of the complete box including type, extended type and size
 *
 * Advances the byte reader to the start of the box content. To skip
 * over the complete box, skip size - header_size bytes.
 *
 * Returns: TRUE if a box header could be parsed, FALSE if more data is needed
 */
gboolean
gst_isoff_parse_box_header (GstByteReader * reader, guint32 * type,
    guint8 extended_type[16], guint * header_size, guint64 * size)
{
  guint header_start_offset;
  guint32 size_field;

  header_start_offset = gst_byte_reader_get_pos (reader);

  if (gst_byte_reader_get_remaining (reader) < 8)
    goto not_enough_data;

  size_field = gst_byte_reader_get_uint32_be_unchecked (reader);
  *type = gst_byte_reader_get_uint32_le_unchecked (reader);

  if (size_field == 1) {
    if (gst_byte_reader_get_remaining (reader) < 8)
      goto not_enough_data;
    *size = gst_byte_reader_get_uint64_be_unchecked (reader);
  } else {
    *size = size_field;
  }

  if (*type == GST_ISOFF_FOURCC_UUID) {
    if (gst_byte_reader_get_remaining (reader) < 16)
      goto not_enough_data;

    if (extended_type)
      memcpy (extended_type, gst_byte_reader_get_data_unchecked (reader, 16),
          16);
  }

  if (header_size)
    *header_size = gst_byte_reader_get_pos (reader) - header_start_offset;

  return TRUE;

not_enough_data:
  gst_byte_reader_set_pos (reader, header_start_offset);
  return FALSE;
}

static void
gst_isoff_trun_box_clear (GstTrunBox * trun)
{
  if (trun->samples)
    g_array_free (trun->samples, TRUE);
}

static void
gst_isoff_traf_box_clear (GstTrafBox * traf)
{
  if (traf->trun)
    g_array_free (traf->trun, TRUE);
}

static gboolean
gst_isoff_mfhd_box_parse (GstMfhdBox * mfhd, GstByteReader * reader)
{
  guint8 version;
  guint32 flags;

  if (gst_byte_reader_get_remaining (reader) != 8)
    return FALSE;

  version = gst_byte_reader_get_uint8_unchecked (reader);
  if (version != 0)
    return FALSE;

  flags = gst_byte_reader_get_uint24_be_unchecked (reader);
  if (flags != 0)
    return FALSE;

  mfhd->sequence_number = gst_byte_reader_get_uint32_be_unchecked (reader);

  return TRUE;
}

static gboolean
gst_isoff_tfhd_box_parse (GstTfhdBox * tfhd, GstByteReader * reader)
{
  memset (tfhd, 0, sizeof (*tfhd));

  if (gst_byte_reader_get_remaining (reader) < 4)
    return FALSE;

  tfhd->version = gst_byte_reader_get_uint8_unchecked (reader);
  if (tfhd->version != 0)
    return FALSE;

  tfhd->flags = gst_byte_reader_get_uint24_be_unchecked (reader);

  if (!gst_byte_reader_get_uint32_be (reader, &tfhd->track_id))
    return FALSE;

  if ((tfhd->flags & GST_TFHD_FLAGS_BASE_DATA_OFFSET_PRESENT) &&
      !gst_byte_reader_get_uint64_be (reader, &tfhd->base_data_offset))
    return FALSE;

  if ((tfhd->flags & GST_TFHD_FLAGS_SAMPLE_DESCRIPTION_INDEX_PRESENT) &&
      !gst_byte_reader_get_uint32_be (reader, &tfhd->sample_description_index))
    return FALSE;

  if ((tfhd->flags & GST_TFHD_FLAGS_DEFAULT_SAMPLE_DURATION_PRESENT) &&
      !gst_byte_reader_get_uint32_be (reader, &tfhd->default_sample_duration))
    return FALSE;

  if ((tfhd->flags & GST_TFHD_FLAGS_DEFAULT_SAMPLE_SIZE_PRESENT) &&
      !gst_byte_reader_get_uint32_be (reader, &tfhd->default_sample_size))
    return FALSE;

  if ((tfhd->flags & GST_TFHD_FLAGS_DEFAULT_SAMPLE_FLAGS_PRESENT) &&
      !gst_byte_reader_get_uint32_be (reader, &tfhd->default_sample_flags))
    return FALSE;

  return TRUE;
}

static gboolean
gst_isoff_trun_box_parse (GstTrunBox * trun, GstByteReader * reader)
{
  gint i;

  memset (trun, 0, sizeof (*trun));

  if (gst_byte_reader_get_remaining (reader) < 4)
    return FALSE;

  trun->version = gst_byte_reader_get_uint8_unchecked (reader);
  if (trun->version != 0 && trun->version != 1)
    return FALSE;

  trun->flags = gst_byte_reader_get_uint24_be_unchecked (reader);

  if (!gst_byte_reader_get_uint32_be (reader, &trun->sample_count))
    return FALSE;

  trun->samples =
      g_array_sized_new (FALSE, FALSE, sizeof (GstTrunSample),
      trun->sample_count);

  if ((trun->flags & GST_TRUN_FLAGS_DATA_OFFSET_PRESENT) &&
      !gst_byte_reader_get_uint32_be (reader, (guint32 *) & trun->data_offset))
    return FALSE;

  if ((trun->flags & GST_TRUN_FLAGS_FIRST_SAMPLE_FLAGS_PRESENT) &&
      !gst_byte_reader_get_uint32_be (reader, &trun->first_sample_flags))
    return FALSE;

  for (i = 0; i < trun->sample_count; i++) {
    GstTrunSample sample = { 0, };

    if ((trun->flags & GST_TRUN_FLAGS_SAMPLE_DURATION_PRESENT) &&
        !gst_byte_reader_get_uint32_be (reader, &sample.sample_duration))
      goto error;

    if ((trun->flags & GST_TRUN_FLAGS_SAMPLE_SIZE_PRESENT) &&
        !gst_byte_reader_get_uint32_be (reader, &sample.sample_size))
      goto error;

    if ((trun->flags & GST_TRUN_FLAGS_SAMPLE_FLAGS_PRESENT) &&
        !gst_byte_reader_get_uint32_be (reader, &sample.sample_flags))
      goto error;

    if ((trun->flags & GST_TRUN_FLAGS_SAMPLE_COMPOSITION_TIME_OFFSETS_PRESENT)
        && !gst_byte_reader_get_uint32_be (reader,
            &sample.sample_composition_time_offset.u))
      goto error;

    g_array_append_val (trun->samples, sample);
  }

  return TRUE;

error:
  gst_isoff_trun_box_clear (trun);
  return FALSE;
}

static gboolean
gst_isoff_traf_box_parse (GstTrafBox * traf, GstByteReader * reader)
{
  gboolean had_tfhd = FALSE;

  memset (traf, 0, sizeof (*traf));
  traf->trun = g_array_new (FALSE, FALSE, sizeof (GstTrunBox));
  g_array_set_clear_func (traf->trun,
      (GDestroyNotify) gst_isoff_trun_box_clear);

  while (gst_byte_reader_get_remaining (reader) > 0) {
    guint32 fourcc;
    guint header_size;
    guint64 size;

    if (!gst_isoff_parse_box_header (reader, &fourcc, NULL, &header_size,
            &size))
      goto error;
    if (gst_byte_reader_get_remaining (reader) < size - header_size)
      goto error;

    switch (fourcc) {
      case GST_ISOFF_FOURCC_TFHD:{
        GstByteReader sub_reader;

        gst_byte_reader_get_sub_reader (reader, &sub_reader,
            size - header_size);
        if (!gst_isoff_tfhd_box_parse (&traf->tfhd, &sub_reader))
          goto error;
        had_tfhd = TRUE;
        break;
      }
      case GST_ISOFF_FOURCC_TRUN:{
        GstByteReader sub_reader;
        GstTrunBox trun;

        gst_byte_reader_get_sub_reader (reader, &sub_reader,
            size - header_size);
        if (!gst_isoff_trun_box_parse (&trun, &sub_reader))
          goto error;

        g_array_append_val (traf->trun, trun);
        break;
      }
      default:
        gst_byte_reader_skip (reader, size - header_size);
        break;
    }
  }

  if (!had_tfhd)
    goto error;

  return TRUE;

error:
  gst_isoff_traf_box_clear (traf);

  return FALSE;
}

GstMoofBox *
gst_isoff_moof_box_parse (GstByteReader * reader)
{
  GstMoofBox *moof;
  gboolean had_mfhd = FALSE;

  moof = g_new0 (GstMoofBox, 1);
  moof->traf = g_array_new (FALSE, FALSE, sizeof (GstTrafBox));
  g_array_set_clear_func (moof->traf,
      (GDestroyNotify) gst_isoff_traf_box_clear);

  while (gst_byte_reader_get_remaining (reader) > 0) {
    guint32 fourcc;
    guint header_size;
    guint64 size;

    if (!gst_isoff_parse_box_header (reader, &fourcc, NULL, &header_size,
            &size))
      goto error;
    if (gst_byte_reader_get_remaining (reader) < size - header_size)
      goto error;

    switch (fourcc) {
      case GST_ISOFF_FOURCC_MFHD:{
        GstByteReader sub_reader;

        gst_byte_reader_get_sub_reader (reader, &sub_reader,
            size - header_size);
        if (!gst_isoff_mfhd_box_parse (&moof->mfhd, &sub_reader))
          goto error;
        had_mfhd = TRUE;
        break;
      }
      case GST_ISOFF_FOURCC_TRAF:{
        GstByteReader sub_reader;
        GstTrafBox traf;

        gst_byte_reader_get_sub_reader (reader, &sub_reader,
            size - header_size);
        if (!gst_isoff_traf_box_parse (&traf, &sub_reader))
          goto error;

        g_array_append_val (moof->traf, traf);
        break;
      }
      default:
        gst_byte_reader_skip (reader, size - header_size);
        break;
    }
  }

  if (!had_mfhd)
    goto error;

  return moof;

error:
  gst_isoff_moof_box_free (moof);
  return NULL;
}

void
gst_isoff_moof_box_free (GstMoofBox * moof)
{
  g_array_free (moof->traf, TRUE);
  g_free (moof);
}

void
gst_isoff_sidx_parser_init (GstSidxParser * parser)
{
  parser->status = GST_ISOFF_SIDX_PARSER_INIT;
  parser->cumulative_entry_size = 0;
  parser->sidx.entries = NULL;
  parser->sidx.entries_count = 0;
}

void
gst_isoff_sidx_parser_clear (GstSidxParser * parser)
{
  g_free (parser->sidx.entries);
  parser->sidx.entries = NULL;
}

static void
gst_isoff_parse_sidx_entry (GstSidxBoxEntry * entry, GstByteReader * reader)
{
  guint32 aux;

  aux = gst_byte_reader_get_uint32_be_unchecked (reader);
  entry->ref_type = aux >> 31;
  entry->size = aux & 0x7FFFFFFF;
  entry->duration = gst_byte_reader_get_uint32_be_unchecked (reader);
  aux = gst_byte_reader_get_uint32_be_unchecked (reader);
  entry->starts_with_sap = aux >> 31;
  entry->sap_type = ((aux >> 28) & 0x7);
  entry->sap_delta_time = aux & 0xFFFFFFF;
}

GstIsoffParserResult
gst_isoff_sidx_parser_add_buffer (GstSidxParser * parser, GstBuffer * buffer,
    guint * consumed)
{
  GstIsoffParserResult res = GST_ISOFF_PARSER_OK;
  GstByteReader reader;
  GstMapInfo info;
  gsize remaining;
  guint32 fourcc;

  if (!gst_buffer_map (buffer, &info, GST_MAP_READ)) {
    *consumed = 0;
    return GST_ISOFF_PARSER_ERROR;
  }

  gst_byte_reader_init (&reader, info.data, info.size);

  switch (parser->status) {
    case GST_ISOFF_SIDX_PARSER_INIT:
      if (!gst_isoff_parse_box_header (&reader, &fourcc, NULL, NULL,
              &parser->size))
        break;

      if (fourcc != GST_ISOFF_FOURCC_SIDX) {
        res = GST_ISOFF_PARSER_UNEXPECTED;
        gst_byte_reader_set_pos (&reader, 0);
        break;
      }

      if (parser->size == 0) {
        res = GST_ISOFF_PARSER_ERROR;
        gst_byte_reader_set_pos (&reader, 0);
        break;
      }

      /* Try again once we have enough data for the FullBox header */
      if (gst_byte_reader_get_remaining (&reader) < 4) {
        gst_byte_reader_set_pos (&reader, 0);
        break;
      }
      parser->sidx.version = gst_byte_reader_get_uint8_unchecked (&reader);
      parser->sidx.flags = gst_byte_reader_get_uint24_le_unchecked (&reader);

      parser->status = GST_ISOFF_SIDX_PARSER_HEADER;

    case GST_ISOFF_SIDX_PARSER_HEADER:
      remaining = gst_byte_reader_get_remaining (&reader);
      if (remaining < 12 + (parser->sidx.version == 0 ? 8 : 16)) {
        break;
      }

      parser->sidx.ref_id = gst_byte_reader_get_uint32_be_unchecked (&reader);
      parser->sidx.timescale =
          gst_byte_reader_get_uint32_be_unchecked (&reader);
      if (parser->sidx.version == 0) {
        parser->sidx.earliest_pts =
            gst_byte_reader_get_uint32_be_unchecked (&reader);
        parser->sidx.first_offset =
            gst_byte_reader_get_uint32_be_unchecked (&reader);
      } else {
        parser->sidx.earliest_pts =
            gst_byte_reader_get_uint64_be_unchecked (&reader);
        parser->sidx.first_offset =
            gst_byte_reader_get_uint64_be_unchecked (&reader);
      }
      /* skip 2 reserved bytes */
      gst_byte_reader_skip_unchecked (&reader, 2);
      parser->sidx.entries_count =
          gst_byte_reader_get_uint16_be_unchecked (&reader);

      GST_LOG ("Timescale: %" G_GUINT32_FORMAT, parser->sidx.timescale);
      GST_LOG ("Earliest pts: %" G_GUINT64_FORMAT, parser->sidx.earliest_pts);
      GST_LOG ("First offset: %" G_GUINT64_FORMAT, parser->sidx.first_offset);

      parser->cumulative_pts =
          gst_util_uint64_scale_int_round (parser->sidx.earliest_pts,
          GST_SECOND, parser->sidx.timescale);

      if (parser->sidx.entries_count) {
        parser->sidx.entries =
            g_malloc (sizeof (GstSidxBoxEntry) * parser->sidx.entries_count);
      }
      parser->sidx.entry_index = 0;

      parser->status = GST_ISOFF_SIDX_PARSER_DATA;

    case GST_ISOFF_SIDX_PARSER_DATA:
      while (parser->sidx.entry_index < parser->sidx.entries_count) {
        GstSidxBoxEntry *entry =
            &parser->sidx.entries[parser->sidx.entry_index];

        remaining = gst_byte_reader_get_remaining (&reader);
        if (remaining < 12)
          break;

        entry->offset = parser->cumulative_entry_size;
        entry->pts = parser->cumulative_pts;
        gst_isoff_parse_sidx_entry (entry, &reader);
        entry->duration = gst_util_uint64_scale_int_round (entry->duration,
            GST_SECOND, parser->sidx.timescale);
        parser->cumulative_entry_size += entry->size;
        parser->cumulative_pts += entry->duration;

        GST_LOG ("Sidx entry %d) offset: %" G_GUINT64_FORMAT ", pts: %"
            GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT " - size %"
            G_GUINT32_FORMAT, parser->sidx.entry_index, entry->offset,
            GST_TIME_ARGS (entry->pts), GST_TIME_ARGS (entry->duration),
            entry->size);

        parser->sidx.entry_index++;
      }

      if (parser->sidx.entry_index == parser->sidx.entries_count)
        parser->status = GST_ISOFF_SIDX_PARSER_FINISHED;
      else
        break;
    case GST_ISOFF_SIDX_PARSER_FINISHED:
      parser->sidx.entry_index = 0;
      res = GST_ISOFF_PARSER_DONE;
      break;
  }

  *consumed = gst_byte_reader_get_pos (&reader);
  gst_buffer_unmap (buffer, &info);
  return res;
}
