/* GStreamer
 * Copyright (C) 2010 Marc-Andre Lureau <marcandre.lureau@gmail.com>
 *
 * m3u8.c:
 *
 * 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 <stdlib.h>
#include <math.h>
#include <errno.h>
#include <glib.h>
#include <string.h>

#include "gstfragmented.h"
#include "m3u8.h"

#define GST_CAT_DEFAULT fragmented_debug

#if !GLIB_CHECK_VERSION (2, 33, 4)
#define g_list_copy_deep gst_g_list_copy_deep
static GList *
gst_g_list_copy_deep (GList * list, GCopyFunc func, gpointer user_data)
{
  list = g_list_copy (list);

  if (func != NULL) {
    GList *l;

    for (l = list; l != NULL; l = l->next) {
      l->data = func (l->data, user_data);
    }
  }

  return list;
}
#endif

static GstM3U8 *gst_m3u8_new (void);
static void gst_m3u8_free (GstM3U8 * m3u8);
static gboolean gst_m3u8_update (GstM3U8Client * client, GstM3U8 * m3u8,
    gchar * data, gboolean * updated);
static GstM3U8MediaFile *gst_m3u8_media_file_new (gchar * uri,
    gchar * title, GstClockTime duration, guint sequence);
static void gst_m3u8_media_file_free (GstM3U8MediaFile * self);
gchar *uri_join (const gchar * uri, const gchar * path);

static GstM3U8 *
gst_m3u8_new (void)
{
  GstM3U8 *m3u8;

  m3u8 = g_new0 (GstM3U8, 1);

  return m3u8;
}

static void
gst_m3u8_set_uri (GstM3U8 * self, gchar * uri, gchar * base_uri, gchar * name)
{
  g_return_if_fail (self != NULL);

  g_free (self->uri);
  self->uri = uri;

  g_free (self->base_uri);
  self->base_uri = base_uri;

  g_free (self->name);
  self->name = name;
}

static void
gst_m3u8_free (GstM3U8 * self)
{
  g_return_if_fail (self != NULL);

  g_free (self->uri);
  g_free (self->base_uri);
  g_free (self->name);
  g_free (self->codecs);

  g_list_foreach (self->files, (GFunc) gst_m3u8_media_file_free, NULL);
  g_list_free (self->files);

  g_free (self->last_data);
  g_list_foreach (self->lists, (GFunc) gst_m3u8_free, NULL);
  g_list_free (self->lists);
  g_list_foreach (self->iframe_lists, (GFunc) gst_m3u8_free, NULL);
  g_list_free (self->iframe_lists);

  g_free (self);
}

static GstM3U8MediaFile *
gst_m3u8_media_file_new (gchar * uri, gchar * title, GstClockTime duration,
    guint sequence)
{
  GstM3U8MediaFile *file;

  file = g_new0 (GstM3U8MediaFile, 1);
  file->uri = uri;
  file->title = title;
  file->duration = duration;
  file->sequence = sequence;

  return file;
}

static void
gst_m3u8_media_file_free (GstM3U8MediaFile * self)
{
  g_return_if_fail (self != NULL);

  g_free (self->title);
  g_free (self->uri);
  g_free (self->key);
  g_free (self);
}

static GstM3U8MediaFile *
gst_m3u8_media_file_copy (const GstM3U8MediaFile * self, gpointer user_data)
{
  g_return_val_if_fail (self != NULL, NULL);

  return gst_m3u8_media_file_new (g_strdup (self->uri), g_strdup (self->title),
      self->duration, self->sequence);
}

static GstM3U8 *
_m3u8_copy (const GstM3U8 * self, GstM3U8 * parent)
{
  GstM3U8 *dup;

  g_return_val_if_fail (self != NULL, NULL);

  dup = gst_m3u8_new ();
  dup->uri = g_strdup (self->uri);
  dup->base_uri = g_strdup (self->base_uri);
  dup->name = g_strdup (self->name);
  dup->endlist = self->endlist;
  dup->version = self->version;
  dup->targetduration = self->targetduration;
  dup->allowcache = self->allowcache;
  dup->bandwidth = self->bandwidth;
  dup->program_id = self->program_id;
  dup->codecs = g_strdup (self->codecs);
  dup->width = self->width;
  dup->height = self->height;
  dup->iframe = self->iframe;
  dup->files =
      g_list_copy_deep (self->files, (GCopyFunc) gst_m3u8_media_file_copy,
      NULL);

  /* private */
  dup->last_data = g_strdup (self->last_data);
  dup->lists = g_list_copy_deep (self->lists, (GCopyFunc) _m3u8_copy, dup);
  dup->iframe_lists =
      g_list_copy_deep (self->iframe_lists, (GCopyFunc) _m3u8_copy, dup);
  /* NOTE: current_variant will get set in gst_m3u8_copy () */
  dup->parent = parent;
  dup->mediasequence = self->mediasequence;
  return dup;
}

static GstM3U8 *
gst_m3u8_copy (const GstM3U8 * self)
{
  GList *entry;
  guint n;

  GstM3U8 *dup = _m3u8_copy (self, NULL);

  if (self->current_variant != NULL) {
    for (n = 0, entry = self->lists; entry; entry = entry->next, n++) {
      if (entry == self->current_variant) {
        dup->current_variant = g_list_nth (dup->lists, n);
        break;
      }
    }

    if (!dup->current_variant) {
      for (n = 0, entry = self->iframe_lists; entry; entry = entry->next, n++) {
        if (entry == self->current_variant) {
          dup->current_variant = g_list_nth (dup->iframe_lists, n);
          break;
        }
      }

      if (!dup->current_variant) {
        GST_ERROR ("Failed to determine current playlist");
      }
    }
  }

  return dup;
}

static gboolean
int_from_string (gchar * ptr, gchar ** endptr, gint * val)
{
  gchar *end;
  gint64 ret;

  g_return_val_if_fail (ptr != NULL, FALSE);
  g_return_val_if_fail (val != NULL, FALSE);

  errno = 0;
  ret = g_ascii_strtoll (ptr, &end, 10);
  if ((errno == ERANGE && (ret == G_MAXINT64 || ret == G_MININT64))
      || (errno != 0 && ret == 0)) {
    GST_WARNING ("%s", g_strerror (errno));
    return FALSE;
  }

  if (ret > G_MAXINT || ret < G_MININT) {
    GST_WARNING ("%s", g_strerror (ERANGE));
    return FALSE;
  }

  if (endptr)
    *endptr = end;

  *val = (gint) ret;

  return end != ptr;
}

static gboolean
int64_from_string (gchar * ptr, gchar ** endptr, gint64 * val)
{
  gchar *end;
  gint64 ret;

  g_return_val_if_fail (ptr != NULL, FALSE);
  g_return_val_if_fail (val != NULL, FALSE);

  errno = 0;
  ret = g_ascii_strtoll (ptr, &end, 10);
  if ((errno == ERANGE && (ret == G_MAXINT64 || ret == G_MININT64))
      || (errno != 0 && ret == 0)) {
    GST_WARNING ("%s", g_strerror (errno));
    return FALSE;
  }

  if (endptr)
    *endptr = end;

  *val = ret;

  return end != ptr;
}

static gboolean
double_from_string (gchar * ptr, gchar ** endptr, gdouble * val)
{
  gchar *end;
  gdouble ret;

  g_return_val_if_fail (ptr != NULL, FALSE);
  g_return_val_if_fail (val != NULL, FALSE);

  errno = 0;
  ret = g_ascii_strtod (ptr, &end);
  if ((errno == ERANGE && (ret == HUGE_VAL || ret == -HUGE_VAL))
      || (errno != 0 && ret == 0)) {
    GST_WARNING ("%s", g_strerror (errno));
    return FALSE;
  }

  if (!isfinite (ret)) {
    GST_WARNING ("%s", g_strerror (ERANGE));
    return FALSE;
  }

  if (endptr)
    *endptr = end;

  *val = (gdouble) ret;

  return end != ptr;
}

static gboolean
parse_attributes (gchar ** ptr, gchar ** a, gchar ** v)
{
  gchar *end = NULL, *p;

  g_return_val_if_fail (ptr != NULL, FALSE);
  g_return_val_if_fail (*ptr != NULL, FALSE);
  g_return_val_if_fail (a != NULL, FALSE);
  g_return_val_if_fail (v != NULL, FALSE);

  /* [attribute=value,]* */

  *a = *ptr;
  end = p = g_utf8_strchr (*ptr, -1, ',');
  if (end) {
    gchar *q = g_utf8_strchr (*ptr, -1, '"');
    if (q && q < end) {
      /* special case, such as CODECS="avc1.77.30, mp4a.40.2" */
      q = g_utf8_next_char (q);
      if (q) {
        q = g_utf8_strchr (q, -1, '"');
      }
      if (q) {
        end = p = g_utf8_strchr (q, -1, ',');
      }
    }
  }
  if (end) {
    do {
      end = g_utf8_next_char (end);
    } while (end && *end == ' ');
    *p = '\0';
  }

  *v = p = g_utf8_strchr (*ptr, -1, '=');
  if (*v) {
    *v = g_utf8_next_char (*v);
    *p = '\0';
  } else {
    GST_WARNING ("missing = after attribute");
    return FALSE;
  }

  *ptr = end;
  return TRUE;
}

static gchar *
unquote_string (gchar * string)
{
  gchar *string_ret;

  string_ret = strchr (string, '"');
  if (string_ret != NULL) {
    /* found initialization quotation mark of string */
    string = string_ret + 1;
    string_ret = strchr (string, '"');
    if (string_ret != NULL) {
      /* found finalizing quotation mark of string */
      string_ret[0] = '\0';
    } else {
      GST_WARNING
          ("wrong string unqouting - cannot find finalizing quotation mark");
      return NULL;
    }
  }
  return string;
}

static gint
_m3u8_compare_uri (GstM3U8 * a, gchar * uri)
{
  g_return_val_if_fail (a != NULL, 0);
  g_return_val_if_fail (uri != NULL, 0);

  return g_strcmp0 (a->uri, uri);
}

static gint
gst_m3u8_compare_playlist_by_bitrate (gconstpointer a, gconstpointer b)
{
  return ((GstM3U8 *) (a))->bandwidth - ((GstM3U8 *) (b))->bandwidth;
}

/*
 * @data: a m3u8 playlist text data, taking ownership
 */
static gboolean
gst_m3u8_update (GstM3U8Client * client, GstM3U8 * self, gchar * data,
    gboolean * updated)
{
  gint val;
  GstClockTime duration;
  gchar *title, *end;
  gboolean discontinuity = FALSE;
  GstM3U8 *list;
  gchar *current_key = NULL;
  gboolean have_iv = FALSE;
  guint8 iv[16] = { 0, };
  gint64 size = -1, offset = -1;

  g_return_val_if_fail (self != NULL, FALSE);
  g_return_val_if_fail (data != NULL, FALSE);
  g_return_val_if_fail (updated != NULL, FALSE);

  *updated = TRUE;

  /* check if the data changed since last update */
  if (self->last_data && g_str_equal (self->last_data, data)) {
    GST_DEBUG ("Playlist is the same as previous one");
    *updated = FALSE;
    g_free (data);
    return TRUE;
  }

  if (!g_str_has_prefix (data, "#EXTM3U")) {
    GST_WARNING ("Data doesn't start with #EXTM3U");
    *updated = FALSE;
    g_free (data);
    return FALSE;
  }

  g_free (self->last_data);
  self->last_data = data;

  client->current_file = NULL;
  if (self->files) {
    g_list_foreach (self->files, (GFunc) gst_m3u8_media_file_free, NULL);
    g_list_free (self->files);
    self->files = NULL;
  }
  client->duration = GST_CLOCK_TIME_NONE;

  /* By default, allow caching */
  self->allowcache = TRUE;

  list = NULL;
  duration = 0;
  title = NULL;
  data += 7;
  while (TRUE) {
    gchar *r;

    end = g_utf8_strchr (data, -1, '\n');
    if (end)
      *end = '\0';

    r = g_utf8_strchr (data, -1, '\r');
    if (r)
      *r = '\0';

    if (data[0] != '#' && data[0] != '\0') {
      gchar *name = data;
      if (duration <= 0 && list == NULL) {
        GST_LOG ("%s: got line without EXTINF or EXTSTREAMINF, dropping", data);
        goto next_line;
      }

      data = uri_join (self->base_uri ? self->base_uri : self->uri, data);
      if (data == NULL)
        goto next_line;

      if (list != NULL) {
        if (g_list_find_custom (self->lists, data,
                (GCompareFunc) _m3u8_compare_uri)) {
          GST_DEBUG ("Already have a list with this URI");
          gst_m3u8_free (list);
          g_free (data);
        } else {
          gst_m3u8_set_uri (list, data, NULL, g_strdup (name));
          self->lists = g_list_append (self->lists, list);
        }
        list = NULL;
      } else {
        GstM3U8MediaFile *file;
        file =
            gst_m3u8_media_file_new (data, title, duration,
            self->mediasequence++);

        /* set encryption params */
        file->key = current_key ? g_strdup (current_key) : NULL;
        if (file->key) {
          if (have_iv) {
            memcpy (file->iv, iv, sizeof (iv));
          } else {
            guint8 *iv = file->iv + 12;
            GST_WRITE_UINT32_BE (iv, file->sequence);
          }
        }

        if (size != -1) {
          file->size = size;
          if (offset != -1) {
            file->offset = offset;
          } else {
            GstM3U8MediaFile *prev = self->files ? self->files->data : NULL;

            if (!prev) {
              offset = 0;
            } else {
              offset = prev->offset + prev->size;
            }
            file->offset = offset;
          }
        } else {
          file->size = -1;
          file->offset = 0;
        }

        file->discont = discontinuity;

        duration = 0;
        title = NULL;
        discontinuity = FALSE;
        size = offset = -1;
        self->files = g_list_prepend (self->files, file);
      }

    } else if (g_str_has_prefix (data, "#EXTINF:")) {
      gdouble fval;
      if (!double_from_string (data + 8, &data, &fval)) {
        GST_WARNING ("Can't read EXTINF duration");
        goto next_line;
      }
      duration = fval * (gdouble) GST_SECOND;
      if (self->targetduration > 0 && duration > self->targetduration) {
        GST_WARNING ("EXTINF duration (%" GST_TIME_FORMAT
            ") > TARGETDURATION (%" GST_TIME_FORMAT ")",
            GST_TIME_ARGS (duration), GST_TIME_ARGS (self->targetduration));
      }
      if (!data || *data != ',')
        goto next_line;
      data = g_utf8_next_char (data);
      if (data != end) {
        g_free (title);
        title = g_strdup (data);
      }
    } else if (g_str_has_prefix (data, "#EXT-X-")) {
      gchar *data_ext_x = data + 7;

      /* All these entries start with #EXT-X- */
      if (g_str_has_prefix (data_ext_x, "ENDLIST")) {
        self->endlist = TRUE;
      } else if (g_str_has_prefix (data_ext_x, "VERSION:")) {
        if (int_from_string (data + 15, &data, &val))
          self->version = val;
      } else if (g_str_has_prefix (data_ext_x, "STREAM-INF:") ||
          g_str_has_prefix (data_ext_x, "I-FRAME-STREAM-INF:")) {
        gchar *v, *a;
        gboolean iframe = g_str_has_prefix (data_ext_x, "I-FRAME-STREAM-INF:");
        GstM3U8 *new_list;

        new_list = gst_m3u8_new ();
        new_list->parent = self;
        new_list->iframe = iframe;
        data = data + (iframe ? 26 : 18);
        while (data && parse_attributes (&data, &a, &v)) {
          if (g_str_equal (a, "BANDWIDTH")) {
            if (!int_from_string (v, NULL, &new_list->bandwidth))
              GST_WARNING ("Error while reading BANDWIDTH");
          } else if (g_str_equal (a, "PROGRAM-ID")) {
            if (!int_from_string (v, NULL, &new_list->program_id))
              GST_WARNING ("Error while reading PROGRAM-ID");
          } else if (g_str_equal (a, "CODECS")) {
            g_free (new_list->codecs);
            new_list->codecs = g_strdup (v);
          } else if (g_str_equal (a, "RESOLUTION")) {
            if (!int_from_string (v, &v, &new_list->width))
              GST_WARNING ("Error while reading RESOLUTION width");
            if (!v || *v != 'x') {
              GST_WARNING ("Missing height");
            } else {
              v = g_utf8_next_char (v);
              if (!int_from_string (v, NULL, &new_list->height))
                GST_WARNING ("Error while reading RESOLUTION height");
            }
          } else if (iframe && g_str_equal (a, "URI")) {
            gchar *name;
            gchar *uri = g_strdup (v);
            gchar *urip = uri;

            uri = unquote_string (uri);
            if (uri) {
              uri = uri_join (self->base_uri ? self->base_uri : self->uri, uri);
              if (uri == NULL) {
                g_free (urip);
                continue;
              }
              name = g_strdup (uri);

              gst_m3u8_set_uri (new_list, uri, NULL, name);
            } else {
              GST_WARNING
                  ("Cannot remove quotation marks from i-frame-stream URI");
            }
            g_free (urip);
          }
        }

        if (iframe) {
          if (g_list_find_custom (self->iframe_lists, new_list->uri,
                  (GCompareFunc) _m3u8_compare_uri)) {
            GST_DEBUG ("Already have a list with this URI");
            gst_m3u8_free (new_list);
          } else {
            self->iframe_lists = g_list_append (self->iframe_lists, new_list);
          }
        } else if (list != NULL) {
          GST_WARNING ("Found a list without a uri..., dropping");
          gst_m3u8_free (list);
        } else {
          list = new_list;
        }
      } else if (g_str_has_prefix (data_ext_x, "TARGETDURATION:")) {
        if (int_from_string (data + 22, &data, &val))
          self->targetduration = val * GST_SECOND;
      } else if (g_str_has_prefix (data_ext_x, "MEDIA-SEQUENCE:")) {
        if (int_from_string (data + 22, &data, &val))
          self->mediasequence = val;
      } else if (g_str_has_prefix (data_ext_x, "DISCONTINUITY")) {
        discontinuity = TRUE;
      } else if (g_str_has_prefix (data_ext_x, "PROGRAM-DATE-TIME:")) {
        /* <YYYY-MM-DDThh:mm:ssZ> */
        GST_DEBUG ("FIXME parse date");
      } else if (g_str_has_prefix (data_ext_x, "ALLOW-CACHE:")) {
        self->allowcache = g_ascii_strcasecmp (data + 19, "YES") == 0;
      } else if (g_str_has_prefix (data_ext_x, "KEY:")) {
        gchar *v, *a;

        data = data + 11;

        /* IV and KEY are only valid until the next #EXT-X-KEY */
        have_iv = FALSE;
        g_free (current_key);
        current_key = NULL;
        while (data && parse_attributes (&data, &a, &v)) {
          if (g_str_equal (a, "URI")) {
            gchar *key = g_strdup (v);
            gchar *keyp = key;

            key = unquote_string (key);
            if (key) {
              current_key =
                  uri_join (self->base_uri ? self->base_uri : self->uri, key);
            } else {
              GST_WARNING
                  ("Cannot remove quotation marks from decryption key URI");
            }
            g_free (keyp);
          } else if (g_str_equal (a, "IV")) {
            gchar *ivp = v;
            gint i;

            if (strlen (ivp) < 32 + 2 || (!g_str_has_prefix (ivp, "0x")
                    && !g_str_has_prefix (ivp, "0X"))) {
              GST_WARNING ("Can't read IV");
              continue;
            }

            ivp += 2;
            for (i = 0; i < 16; i++) {
              gint h, l;

              h = g_ascii_xdigit_value (*ivp);
              ivp++;
              l = g_ascii_xdigit_value (*ivp);
              ivp++;
              if (h == -1 || l == -1) {
                i = -1;
                break;
              }
              iv[i] = (h << 4) | l;
            }

            if (i == -1) {
              GST_WARNING ("Can't read IV");
              continue;
            }
            have_iv = TRUE;
          } else if (g_str_equal (a, "METHOD")) {
            if (!g_str_equal (v, "AES-128")) {
              GST_WARNING ("Encryption method %s not supported", v);
              continue;
            }
          }
        }
      } else if (g_str_has_prefix (data_ext_x, "BYTERANGE:")) {
        gchar *v = data + 17;

        if (int64_from_string (v, &v, &size)) {
          if (*v == '@' && !int64_from_string (v + 1, &v, &offset))
            goto next_line;
        } else {
          goto next_line;
        }
      } else {
        GST_LOG ("Ignored line: %s", data);
      }
    } else {
      GST_LOG ("Ignored line: %s", data);
    }

  next_line:
    if (!end)
      break;
    data = g_utf8_next_char (end);      /* skip \n */
  }

  g_free (current_key);
  current_key = NULL;

  self->files = g_list_reverse (self->files);

  /* reorder playlists by bitrate */
  if (self->lists) {
    gchar *top_variant_uri = NULL;
    gboolean iframe = FALSE;

    if (!self->current_variant) {
      top_variant_uri = GST_M3U8 (self->lists->data)->uri;
    } else {
      top_variant_uri = GST_M3U8 (self->current_variant->data)->uri;
      iframe = GST_M3U8 (self->current_variant->data)->iframe;
    }

    self->lists =
        g_list_sort (self->lists,
        (GCompareFunc) gst_m3u8_compare_playlist_by_bitrate);

    self->iframe_lists =
        g_list_sort (self->iframe_lists,
        (GCompareFunc) gst_m3u8_compare_playlist_by_bitrate);

    if (iframe)
      self->current_variant =
          g_list_find_custom (self->iframe_lists, top_variant_uri,
          (GCompareFunc) _m3u8_compare_uri);
    else
      self->current_variant = g_list_find_custom (self->lists, top_variant_uri,
          (GCompareFunc) _m3u8_compare_uri);
  }
  /* calculate the start and end times of this media playlist. */
  if (self->files) {
    GList *walk;
    GstM3U8MediaFile *file;
    GstClockTime duration = 0;

    for (walk = self->files; walk; walk = walk->next) {
      file = walk->data;
      duration += file->duration;
      if (file->sequence > client->highest_sequence_number) {
        if (client->highest_sequence_number >= 0) {
          /* if an update of the media playlist has been missed, there
             will be a gap between self->highest_sequence_number and the
             first sequence number in this media playlist. In this situation
             assume that the missing fragments had a duration of
             targetduration each */
          client->last_file_end +=
              (file->sequence - client->highest_sequence_number -
              1) * self->targetduration;
        }
        client->last_file_end += file->duration;
        client->highest_sequence_number = file->sequence;
      }
    }
    if (GST_M3U8_CLIENT_IS_LIVE (client)) {
      client->first_file_start = client->last_file_end - duration;
      GST_DEBUG ("Live playlist range %" GST_TIME_FORMAT " -> %"
          GST_TIME_FORMAT, GST_TIME_ARGS (client->first_file_start),
          GST_TIME_ARGS (client->last_file_end));
    }
    client->duration = duration;
  }

  return TRUE;
}

GstM3U8Client *
gst_m3u8_client_new (const gchar * uri, const gchar * base_uri)
{
  GstM3U8Client *client;

  g_return_val_if_fail (uri != NULL, NULL);

  client = g_new0 (GstM3U8Client, 1);
  client->main = gst_m3u8_new ();
  client->current = NULL;
  client->current_file = NULL;
  client->sequence = -1;
  client->sequence_position = 0;
  client->update_failed_count = 0;
  client->highest_sequence_number = -1;
  client->duration = GST_CLOCK_TIME_NONE;
  g_mutex_init (&client->lock);
  gst_m3u8_set_uri (client->main, g_strdup (uri), g_strdup (base_uri), NULL);

  return client;
}

void
gst_m3u8_client_free (GstM3U8Client * self)
{
  g_return_if_fail (self != NULL);

  gst_m3u8_free (self->main);
  g_mutex_clear (&self->lock);
  g_free (self);
}

void
gst_m3u8_client_set_current (GstM3U8Client * self, GstM3U8 * m3u8)
{
  g_return_if_fail (self != NULL);

  GST_M3U8_CLIENT_LOCK (self);
  if (m3u8 != self->current) {
    self->current = m3u8;
    self->update_failed_count = 0;
    self->duration = GST_CLOCK_TIME_NONE;
    self->current_file = NULL;
  }
  GST_M3U8_CLIENT_UNLOCK (self);
}

gboolean
gst_m3u8_client_update (GstM3U8Client * self, gchar * data)
{
  GstM3U8 *m3u8;
  gboolean updated = FALSE;
  gboolean ret = FALSE;

  g_return_val_if_fail (self != NULL, FALSE);

  GST_M3U8_CLIENT_LOCK (self);
  m3u8 = self->current ? self->current : self->main;

  if (!gst_m3u8_update (self, m3u8, data, &updated))
    goto out;

  if (!updated) {
    self->update_failed_count++;
    goto out;
  }

  if (self->current && !self->current->files) {
    GST_ERROR ("Invalid media playlist, it does not contain any media files");
    goto out;
  }

  /* select the first playlist, for now */
  if (!self->current) {
    if (self->main->lists) {
      self->current = self->main->current_variant->data;
    } else {
      self->current = self->main;
    }
  }

  if (m3u8->files && self->sequence == -1) {
    if (GST_M3U8_CLIENT_IS_LIVE (self)) {
      /* for live streams, start GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE from
         the end of the playlist. See section 6.3.3 of HLS draft */
      gint pos =
          g_list_length (m3u8->files) - GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE;
      self->current_file = g_list_nth (m3u8->files, pos >= 0 ? pos : 0);
    } else {
      self->current_file = g_list_first (m3u8->files);
    }
    self->sequence = GST_M3U8_MEDIA_FILE (self->current_file->data)->sequence;
    self->sequence_position = 0;
    GST_DEBUG ("Setting first sequence at %u", (guint) self->sequence);
  }

  ret = TRUE;
out:
  GST_M3U8_CLIENT_UNLOCK (self);
  return ret;
}

static gint
_find_m3u8_list_match (const GstM3U8 * a, const GstM3U8 * b)
{
  if (g_strcmp0 (a->name, b->name) == 0 &&
      a->bandwidth == b->bandwidth &&
      a->program_id == b->program_id &&
      g_strcmp0 (a->codecs, b->codecs) == 0 &&
      a->width == b->width &&
      a->height == b->height && a->iframe == b->iframe) {
    return 0;
  }

  return 1;
}

gboolean
gst_m3u8_client_update_variant_playlist (GstM3U8Client * self, gchar * data,
    const gchar * uri, const gchar * base_uri)
{
  gboolean ret = FALSE;
  GList *list_entry, *unmatched_lists;
  GstM3U8Client *new_client;
  GstM3U8 *old;

  g_return_val_if_fail (self != NULL, FALSE);

  new_client = gst_m3u8_client_new (uri, base_uri);
  if (gst_m3u8_client_update (new_client, data)) {
    if (!new_client->main->lists) {
      GST_ERROR
          ("Cannot update variant playlist: New playlist is not a variant playlist");
      gst_m3u8_client_free (new_client);
      return FALSE;
    }

    GST_M3U8_CLIENT_LOCK (self);

    if (!self->main->lists) {
      GST_ERROR
          ("Cannot update variant playlist: Current playlist is not a variant playlist");
      goto out;
    }

    /* Now see if the variant playlist still has the same lists */
    unmatched_lists = g_list_copy (self->main->lists);
    for (list_entry = new_client->main->lists; list_entry;
        list_entry = list_entry->next) {
      GList *match = g_list_find_custom (unmatched_lists, list_entry->data,
          (GCompareFunc) _find_m3u8_list_match);
      if (match)
        unmatched_lists = g_list_remove_link (unmatched_lists, match);
    }

    if (unmatched_lists != NULL) {
      GST_WARNING ("Unable to match all playlists");

      for (list_entry = unmatched_lists; list_entry;
          list_entry = list_entry->next) {
        if (list_entry->data == self->current) {
          GST_WARNING ("Unable to match current playlist");
        }
      }

      g_list_free (unmatched_lists);
    }

    /* Switch out the variant playlist */
    old = self->main;

    self->main = gst_m3u8_copy (new_client->main);
    if (self->main->lists)
      self->current = self->main->current_variant->data;
    else
      self->current = self->main;

    gst_m3u8_free (old);

    ret = TRUE;

  out:
    GST_M3U8_CLIENT_UNLOCK (self);
  }

  gst_m3u8_client_free (new_client);
  return ret;
}

static gboolean
_find_current (GstM3U8MediaFile * file, GstM3U8Client * client)
{
  return file->sequence != client->sequence;
}

static GList *
find_next_fragment (GstM3U8Client * client, GList * l, gboolean forward)
{
  GstM3U8MediaFile *file;

  if (forward) {
    while (l) {
      file = l->data;

      if (file->sequence >= client->sequence)
        break;

      l = l->next;
    }
  } else {
    l = g_list_last (l);

    while (l) {
      file = l->data;

      if (file->sequence <= client->sequence)
        break;

      l = l->prev;
    }
  }

  return l;
}

static gboolean
has_next_fragment (GstM3U8Client * client, GList * l, gboolean forward)
{
  l = find_next_fragment (client, l, forward);

  if (l) {
    return (forward && l->next) || (!forward && l->prev);
  }

  return FALSE;
}

gboolean
gst_m3u8_client_get_next_fragment (GstM3U8Client * client,
    gboolean * discontinuity, gchar ** uri, GstClockTime * duration,
    GstClockTime * timestamp, gint64 * range_start, gint64 * range_end,
    gchar ** key, guint8 ** iv, gboolean forward)
{
  GstM3U8MediaFile *file;

  g_return_val_if_fail (client != NULL, FALSE);
  g_return_val_if_fail (client->current != NULL, FALSE);

  GST_M3U8_CLIENT_LOCK (client);
  GST_DEBUG ("Looking for fragment %" G_GINT64_FORMAT, client->sequence);
  if (client->sequence < 0) {
    GST_M3U8_CLIENT_UNLOCK (client);
    return FALSE;
  }
  if (!client->current_file) {
    client->current_file =
        find_next_fragment (client, client->current->files, forward);
  }

  if (!client->current_file) {
    GST_M3U8_CLIENT_UNLOCK (client);
    return FALSE;
  }

  file = GST_M3U8_MEDIA_FILE (client->current_file->data);
  GST_DEBUG ("Got fragment with sequence %u (client sequence %u)",
      (guint) file->sequence, (guint) client->sequence);

  if (timestamp)
    *timestamp = client->sequence_position;

  if (discontinuity)
    *discontinuity = client->sequence != file->sequence || file->discont;
  if (uri)
    *uri = g_strdup (file->uri);
  if (duration)
    *duration = file->duration;
  if (range_start)
    *range_start = file->offset;
  if (range_end)
    *range_end = file->size != -1 ? file->offset + file->size - 1 : -1;
  if (key)
    *key = g_strdup (file->key);
  if (iv) {
    *iv = g_new (guint8, sizeof (file->iv));
    memcpy (*iv, file->iv, sizeof (file->iv));
  }

  client->sequence = file->sequence;

  GST_M3U8_CLIENT_UNLOCK (client);
  return TRUE;
}

gboolean
gst_m3u8_client_has_next_fragment (GstM3U8Client * client, gboolean forward)
{
  gboolean ret;

  g_return_val_if_fail (client != NULL, FALSE);
  g_return_val_if_fail (client->current != NULL, FALSE);

  GST_M3U8_CLIENT_LOCK (client);
  GST_DEBUG ("Checking if has next fragment %" G_GINT64_FORMAT,
      client->sequence + (forward ? 1 : -1));
  if (client->current_file) {
    ret =
        (forward ? client->current_file->next : client->current_file->prev) !=
        NULL;
  } else {
    ret = has_next_fragment (client, client->current->files, forward);
  }
  GST_M3U8_CLIENT_UNLOCK (client);
  return ret;
}

static void
alternate_advance (GstM3U8Client * client, gboolean forward)
{
  gint targetnum = client->sequence;
  GList *tmp;
  GstM3U8MediaFile *mf;

  /* figure out the target seqnum */
  if (forward)
    targetnum += 1;
  else
    targetnum -= 1;

  for (tmp = client->current->files; tmp; tmp = tmp->next) {
    mf = (GstM3U8MediaFile *) tmp->data;
    if (mf->sequence == targetnum)
      break;
  }
  if (tmp == NULL) {
    GST_WARNING ("Can't find next fragment");
    return;
  }
  client->current_file = tmp;
  client->sequence = targetnum;
  if (forward)
    client->sequence_position += mf->duration;
  else {
    if (client->sequence_position > mf->duration)
      client->sequence_position -= mf->duration;
    else
      client->sequence_position = 0;
  }
}

void
gst_m3u8_client_advance_fragment (GstM3U8Client * client, gboolean forward)
{
  GstM3U8MediaFile *file;

  g_return_if_fail (client != NULL);
  g_return_if_fail (client->current != NULL);

  GST_M3U8_CLIENT_LOCK (client);
  if (!client->current_file) {
    GList *l;

    GST_DEBUG ("Looking for fragment %" G_GINT64_FORMAT, client->sequence);
    l = g_list_find_custom (client->current->files, client,
        (GCompareFunc) _find_current);
    if (l == NULL) {
      GST_DEBUG
          ("Could not find current fragment, trying next fragment directly");
      alternate_advance (client, forward);
      GST_M3U8_CLIENT_UNLOCK (client);
      return;
    }
    client->current_file = l;
  }

  file = GST_M3U8_MEDIA_FILE (client->current_file->data);
  GST_DEBUG ("Advancing from sequence %u", (guint) file->sequence);
  if (forward) {
    client->current_file = client->current_file->next;
    if (client->current_file) {
      client->sequence =
          GST_M3U8_MEDIA_FILE (client->current_file->data)->sequence;
    } else {
      client->sequence = file->sequence + 1;
    }

    client->sequence_position += file->duration;
  } else {
    client->current_file = client->current_file->prev;
    if (client->current_file) {
      client->sequence =
          GST_M3U8_MEDIA_FILE (client->current_file->data)->sequence;
    } else {
      client->sequence = file->sequence - 1;
    }

    if (client->sequence_position > file->duration)
      client->sequence_position -= file->duration;
    else
      client->sequence_position = 0;
  }
  GST_M3U8_CLIENT_UNLOCK (client);
}

static void
_sum_duration (GstM3U8MediaFile * self, GstClockTime * duration)
{
  *duration += self->duration;
}

GstClockTime
gst_m3u8_client_get_duration (GstM3U8Client * client)
{
  GstClockTime duration = GST_CLOCK_TIME_NONE;

  g_return_val_if_fail (client != NULL, GST_CLOCK_TIME_NONE);

  GST_M3U8_CLIENT_LOCK (client);
  /* We can only get the duration for on-demand streams */
  if (!client->current || !client->current->endlist) {
    GST_M3U8_CLIENT_UNLOCK (client);
    return GST_CLOCK_TIME_NONE;
  }

  if (!GST_CLOCK_TIME_IS_VALID (client->duration) && client->current->files) {
    client->duration = 0;
    g_list_foreach (client->current->files, (GFunc) _sum_duration,
        &client->duration);
  }
  duration = client->duration;
  GST_M3U8_CLIENT_UNLOCK (client);

  return duration;
}

GstClockTime
gst_m3u8_client_get_target_duration (GstM3U8Client * client)
{
  GstClockTime duration = 0;

  g_return_val_if_fail (client != NULL, GST_CLOCK_TIME_NONE);

  GST_M3U8_CLIENT_LOCK (client);
  duration = client->current->targetduration;
  GST_M3U8_CLIENT_UNLOCK (client);
  return duration;
}

gchar *
gst_m3u8_client_get_uri (GstM3U8Client * client)
{
  gchar *uri;

  g_return_val_if_fail (client != NULL, NULL);

  GST_M3U8_CLIENT_LOCK (client);
  uri = client->main ? g_strdup (client->main->uri) : NULL;
  GST_M3U8_CLIENT_UNLOCK (client);
  return uri;
}

gchar *
gst_m3u8_client_get_current_uri (GstM3U8Client * client)
{
  gchar *uri;

  g_return_val_if_fail (client != NULL, NULL);

  GST_M3U8_CLIENT_LOCK (client);
  uri = g_strdup (client->current->uri);
  GST_M3U8_CLIENT_UNLOCK (client);
  return uri;
}

gboolean
gst_m3u8_client_has_main (GstM3U8Client * client)
{
  gboolean ret;

  g_return_val_if_fail (client != NULL, FALSE);

  GST_M3U8_CLIENT_LOCK (client);
  if (client->main)
    ret = TRUE;
  else
    ret = FALSE;
  GST_M3U8_CLIENT_UNLOCK (client);
  return ret;
}

gboolean
gst_m3u8_client_has_variant_playlist (GstM3U8Client * client)
{
  gboolean ret;

  g_return_val_if_fail (client != NULL, FALSE);

  GST_M3U8_CLIENT_LOCK (client);
  ret = (client->main->lists != NULL);
  GST_M3U8_CLIENT_UNLOCK (client);
  return ret;
}

gboolean
gst_m3u8_client_is_live (GstM3U8Client * client)
{
  gboolean ret;

  g_return_val_if_fail (client != NULL, FALSE);

  GST_M3U8_CLIENT_LOCK (client);
  ret = GST_M3U8_CLIENT_IS_LIVE (client);
  GST_M3U8_CLIENT_UNLOCK (client);
  return ret;
}

GList *
gst_m3u8_client_get_playlist_for_bitrate (GstM3U8Client * client, guint bitrate)
{
  GList *list, *current_variant;

  GST_M3U8_CLIENT_LOCK (client);
  current_variant = client->main->current_variant;

  /*  Go to the highest possible bandwidth allowed */
  while (GST_M3U8 (current_variant->data)->bandwidth <= bitrate) {
    list = g_list_next (current_variant);
    if (!list)
      break;
    current_variant = list;
  }

  while (GST_M3U8 (current_variant->data)->bandwidth > bitrate) {
    list = g_list_previous (current_variant);
    if (!list)
      break;
    current_variant = list;
  }
  GST_M3U8_CLIENT_UNLOCK (client);

  return current_variant;
}

gchar *
uri_join (const gchar * uri1, const gchar * uri2)
{
  gchar *uri_copy, *tmp, *ret = NULL;

  if (gst_uri_is_valid (uri2))
    return g_strdup (uri2);

  uri_copy = g_strdup (uri1);
  if (uri2[0] != '/') {
    /* uri2 is a relative uri2 */
    /* look for query params */
    tmp = g_utf8_strchr (uri_copy, -1, '?');
    if (tmp) {
      /* find last / char, ignoring query params */
      tmp = g_utf8_strrchr (uri_copy, tmp - uri_copy, '/');
    } else {
      /* find last / char in URL */
      tmp = g_utf8_strrchr (uri_copy, -1, '/');
    }
    if (!tmp) {
      GST_WARNING ("Can't build a valid uri_copy");
      goto out;
    }

    *tmp = '\0';
    ret = g_strdup_printf ("%s/%s", uri_copy, uri2);
  } else {
    /* uri2 is an absolute uri2 */
    char *scheme, *hostname;

    scheme = uri_copy;
    /* find the : in <scheme>:// */
    tmp = g_utf8_strchr (uri_copy, -1, ':');
    if (!tmp) {
      GST_WARNING ("Can't build a valid uri_copy");
      goto out;
    }

    *tmp = '\0';

    /* skip :// */
    hostname = tmp + 3;

    tmp = g_utf8_strchr (hostname, -1, '/');
    if (tmp)
      *tmp = '\0';

    ret = g_strdup_printf ("%s://%s%s", scheme, hostname, uri2);
  }

out:
  g_free (uri_copy);
  return ret;
}

guint64
gst_m3u8_client_get_current_fragment_duration (GstM3U8Client * client)
{
  guint64 dur;
  GList *list;

  g_return_val_if_fail (client != NULL, 0);

  GST_M3U8_CLIENT_LOCK (client);

  list = g_list_find_custom (client->current->files, client,
      (GCompareFunc) _find_current);
  if (list == NULL) {
    dur = -1;
  } else {
    dur = GST_M3U8_MEDIA_FILE (list->data)->duration;
  }

  GST_M3U8_CLIENT_UNLOCK (client);
  return dur;
}

gboolean
gst_m3u8_client_get_seek_range (GstM3U8Client * client, gint64 * start,
    gint64 * stop)
{
  GstClockTime duration = 0;
  GList *walk;
  GstM3U8MediaFile *file;
  guint count;

  g_return_val_if_fail (client != NULL, FALSE);

  GST_M3U8_CLIENT_LOCK (client);

  if (client->current == NULL || client->current->files == NULL) {
    GST_M3U8_CLIENT_UNLOCK (client);
    return FALSE;
  }

  count = g_list_length (client->current->files);

  /* count is used to make sure the seek range is never closer than
     GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE fragments from the end of the
     playlist - see 6.3.3. "Playing the Playlist file" of the HLS draft */
  for (walk = client->current->files;
      walk && count >= GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE; walk = walk->next) {
    file = walk->data;
    --count;
    duration += file->duration;
  }

  if (duration <= 0) {
    GST_M3U8_CLIENT_UNLOCK (client);
    return FALSE;
  }
  *start = client->first_file_start;
  *stop = *start + duration;
  GST_M3U8_CLIENT_UNLOCK (client);
  return TRUE;
}
