/* GStreamer
 * Copyright (C) 2013 Fluendo S.L. <support@fluendo.com>
 *   Authors:    2013 Andoni Morales Alastruey <amorales@fluendo.com>
 * Copyright (C) 2013 Sebastian Dröge <slomo@circular-chaos.org>
 *
 * gstios_assetsrc.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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
/**
 * SECTION:element-ios_assetsrc
 * @see_also: #GstIOSAssetSrc
 *
 * Read data from an iOS asset from the media library.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 iosassetsrc uri=assets-library://asset/asset.M4V?id=11&ext=M4V ! decodebin ! autoaudiosink
 * ]| Plays asset with id a song.ogg from local dir.
 * </refsect2>
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <gst/gst.h>
#include <gst/base/base.h>
#include "iosassetsrc.h"

static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

GST_DEBUG_CATEGORY_STATIC (gst_ios_asset_src_debug);
#define GST_CAT_DEFAULT gst_ios_asset_src_debug


#define DEFAULT_BLOCKSIZE       4*1024
#define OBJC_CALLOUT_BEGIN() \
   NSAutoreleasePool *pool; \
   \
   pool = [[NSAutoreleasePool alloc] init]
#define OBJC_CALLOUT_END() \
  [pool release]

enum
{
  PROP_0,
  PROP_URI,
};

static void gst_ios_asset_src_finalize (GObject * object);

static void gst_ios_asset_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_ios_asset_src_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static gboolean gst_ios_asset_src_start (GstBaseSrc * basesrc);
static gboolean gst_ios_asset_src_stop (GstBaseSrc * basesrc);

static gboolean gst_ios_asset_src_is_seekable (GstBaseSrc * src);
static gboolean gst_ios_asset_src_get_size (GstBaseSrc * src, guint64 * size);
static GstFlowReturn gst_ios_asset_src_create (GstBaseSrc * src, guint64 offset,
    guint length, GstBuffer ** buffer);
static gboolean gst_ios_asset_src_query (GstBaseSrc * src, GstQuery * query);

static void gst_ios_asset_src_uri_handler_init (gpointer g_iface,
    gpointer iface_data);

static void
_do_init (GType ios_assetsrc_type)
{
  static const GInterfaceInfo urihandler_info = {
    gst_ios_asset_src_uri_handler_init,
    NULL,
    NULL
  };

  g_type_add_interface_static (ios_assetsrc_type, GST_TYPE_URI_HANDLER,
      &urihandler_info);
  GST_DEBUG_CATEGORY_INIT (gst_ios_asset_src_debug, "iosassetsrc", 0, "iosassetsrc element");
}

G_DEFINE_TYPE_WITH_CODE (GstIOSAssetSrc, gst_ios_asset_src, GST_TYPE_BASE_SRC,
    _do_init (g_define_type_id));

static void
gst_ios_asset_src_class_init (GstIOSAssetSrcClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBaseSrcClass *gstbasesrc_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gstelement_class = GST_ELEMENT_CLASS (klass);
  gstbasesrc_class = GST_BASE_SRC_CLASS (klass);

  gobject_class->set_property = gst_ios_asset_src_set_property;
  gobject_class->get_property = gst_ios_asset_src_get_property;

  g_object_class_install_property (gobject_class, PROP_URI,
      g_param_spec_string ("uri", "Asset URI",
          "URI of the asset to read", NULL,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
          GST_PARAM_MUTABLE_READY));

  gobject_class->finalize = gst_ios_asset_src_finalize;

  gst_element_class_set_static_metadata (gstelement_class,
      "IOSAsset Source",
      "Source/File",
      "Read from arbitrary point in a iOS asset",
      "Andoni Morales Alastruey <amorales@fluendo.com>");

  gst_element_class_add_static_pad_template (gstelement_class, &srctemplate);

  gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_ios_asset_src_start);
  gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_ios_asset_src_stop);
  gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_ios_asset_src_is_seekable);
  gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_ios_asset_src_get_size);
  gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_ios_asset_src_create);
  gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_ios_asset_src_query);
}

static void
gst_ios_asset_src_init (GstIOSAssetSrc * src)
{
  OBJC_CALLOUT_BEGIN ();
  src->uri = NULL;
  src->asset = NULL;
  src->library = [[[GstAssetsLibrary alloc] init] retain];
  gst_base_src_set_blocksize (GST_BASE_SRC (src), DEFAULT_BLOCKSIZE);
  OBJC_CALLOUT_END ();
}

static void
gst_ios_asset_src_free_resources (GstIOSAssetSrc *src)
{
  OBJC_CALLOUT_BEGIN ();
  if (src->asset != NULL) {
    [src->asset release];
    src->asset = NULL;
  }

  if (src->url != NULL) {
    [src->url release];
    src->url = NULL;
  }

  if (src->uri != NULL) {
    g_free (src->uri);
    src->uri = NULL;
  }
  OBJC_CALLOUT_END ();
}

static void
gst_ios_asset_src_finalize (GObject * object)
{
  GstIOSAssetSrc *src;

  OBJC_CALLOUT_BEGIN ();
  src = GST_IOS_ASSET_SRC (object);
  gst_ios_asset_src_free_resources (src);
  [src->library release];

  OBJC_CALLOUT_END ();
  G_OBJECT_CLASS (gst_ios_asset_src_parent_class)->finalize (object);
}

static gboolean
gst_ios_asset_src_set_uri (GstIOSAssetSrc * src, const gchar * uri, GError **err)
{
  GstState state;
  NSString *nsuristr;
  NSURL *url;

  OBJC_CALLOUT_BEGIN ();
  /* the element must be stopped in order to do this */
  GST_OBJECT_LOCK (src);
  state = GST_STATE (src);
  if (state != GST_STATE_READY && state != GST_STATE_NULL)
    goto wrong_state;
  GST_OBJECT_UNLOCK (src);

  gst_ios_asset_src_free_resources (src);

  nsuristr = [[NSString alloc] initWithUTF8String:uri];
  url = [[NSURL alloc] initWithString:nsuristr];

  if (url == NULL) {
    GST_ERROR_OBJECT (src, "Invalid URI: %s", uri);
    g_set_error (err, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
        "Invalid URI: %s", uri);
    return FALSE;
  }

  GST_INFO_OBJECT (src, "URI      : %s", src->uri);
  src->url = url;
  src->uri = g_strdup (uri);
  g_object_notify (G_OBJECT (src), "uri");

  OBJC_CALLOUT_END ();
  return TRUE;

  /* ERROR */
wrong_state:
  {
    g_warning ("Changing the 'uri' property on iosassetsrc when an asset is "
        "open is not supported.");
    g_set_error (err, GST_URI_ERROR, GST_URI_ERROR_BAD_STATE,
        "Changing the 'uri' property on iosassetsrc when an asset is "
        "open is not supported.");
    GST_OBJECT_UNLOCK (src);
    OBJC_CALLOUT_END ();
    return FALSE;
  }
}

static void
gst_ios_asset_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstIOSAssetSrc *src;

  g_return_if_fail (GST_IS_IOS_ASSET_SRC (object));

  src = GST_IOS_ASSET_SRC (object);

  switch (prop_id) {
    case PROP_URI:
      gst_ios_asset_src_set_uri (src, g_value_get_string (value), NULL);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_ios_asset_src_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstIOSAssetSrc *src;

  g_return_if_fail (GST_IS_IOS_ASSET_SRC (object));

  src = GST_IOS_ASSET_SRC (object);

  switch (prop_id) {
    case PROP_URI:
      g_value_set_string (value, src->uri);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static GstFlowReturn
gst_ios_asset_src_create (GstBaseSrc * basesrc, guint64 offset, guint length,
    GstBuffer ** buffer)
{
  GstBuffer *buf = NULL;
  GstMapInfo info;
  NSError *err = nil;
  guint bytes_read;
  GstFlowReturn ret;
  GstIOSAssetSrc *src = GST_IOS_ASSET_SRC (basesrc);

  OBJC_CALLOUT_BEGIN ();
  buf = gst_buffer_new_and_alloc (length);
  if (G_UNLIKELY (buf == NULL && length > 0)) {
    GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", length);
    ret = GST_FLOW_ERROR;
    goto exit;
  }

  gst_buffer_map (buf, &info, GST_MAP_READWRITE);

  /* No need to read anything if length is 0 */
  bytes_read = [src->asset getBytes: info.data
                           fromOffset:offset
                           length:length
                           error:&err];
  if (G_UNLIKELY (err != NULL)) {
    goto could_not_read;
  }

  /* we should eos if we read less than what was requested */
  if (G_UNLIKELY (bytes_read < length)) {
    GST_DEBUG ("EOS");
    ret = GST_FLOW_EOS;
  } else {
    ret = GST_FLOW_OK;
  }

  gst_buffer_unmap (buf, &info);
  gst_buffer_set_size (buf, bytes_read);

  GST_BUFFER_OFFSET (buf) = offset;
  GST_BUFFER_OFFSET_END (buf) = offset + bytes_read;

  *buffer = buf;

  goto exit;

  /* ERROR */
could_not_read:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
    gst_buffer_unmap (buf, &info);
    gst_buffer_unref (buf);
    ret = GST_FLOW_ERROR;
    goto exit;
  }
exit:
  {
    OBJC_CALLOUT_END ();
    return ret;
  }

}

static gboolean
gst_ios_asset_src_query (GstBaseSrc * basesrc, GstQuery * query)
{
  gboolean ret = FALSE;
  GstIOSAssetSrc *src = GST_IOS_ASSET_SRC (basesrc);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_URI:
      gst_query_set_uri (query, src->uri);
      ret = TRUE;
      break;
    default:
      ret = FALSE;
      break;
  }

  if (!ret)
    ret = GST_BASE_SRC_CLASS (gst_ios_asset_src_parent_class)->query (basesrc, query);

  return ret;
}

static gboolean
gst_ios_asset_src_is_seekable (GstBaseSrc * basesrc)
{
  return TRUE;
}

static gboolean
gst_ios_asset_src_get_size (GstBaseSrc * basesrc, guint64 * size)
{
  GstIOSAssetSrc *src;

  src = GST_IOS_ASSET_SRC (basesrc);

  OBJC_CALLOUT_BEGIN ();
  *size = (guint64) [src->asset size];
  OBJC_CALLOUT_END ();
  return TRUE;
}

static gboolean
gst_ios_asset_src_start (GstBaseSrc * basesrc)
{
  GstIOSAssetSrc *src = GST_IOS_ASSET_SRC (basesrc);
  gboolean ret = TRUE;

  OBJC_CALLOUT_BEGIN ();
  src->asset = [[src->library assetForURLSync: src->url] retain];

  if (src->asset == NULL) {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
        ("Could not open asset \"%s\" for reading.", src->uri),
        GST_ERROR_SYSTEM);
    ret = FALSE;
  };

  OBJC_CALLOUT_END ();
  return ret;
}

/* unmap and close the ios_asset */
static gboolean
gst_ios_asset_src_stop (GstBaseSrc * basesrc)
{
  GstIOSAssetSrc *src = GST_IOS_ASSET_SRC (basesrc);

  OBJC_CALLOUT_BEGIN ();
  [src->asset release];
  OBJC_CALLOUT_END ();
  return TRUE;
}

static GstURIType
gst_ios_asset_src_uri_get_type (GType type)
{
  return GST_URI_SRC;
}

static const gchar * const *
gst_ios_asset_src_uri_get_protocols (GType type)
{
  static const gchar * const protocols[] = { "assets-library", NULL };

  return protocols;
}

static gchar *
gst_ios_asset_src_uri_get_uri (GstURIHandler * handler)
{
  GstIOSAssetSrc *src = GST_IOS_ASSET_SRC (handler);

  return g_strdup (src->uri);
}

static gboolean
gst_ios_asset_src_uri_set_uri (GstURIHandler * handler, const gchar * uri, GError **err)
{
  GstIOSAssetSrc *src = GST_IOS_ASSET_SRC (handler);

  if (! g_str_has_prefix (uri, "assets-library://")) {
    GST_WARNING_OBJECT (src, "Invalid URI '%s' for ios_assetsrc", uri);
    g_set_error (err, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
        "Invalid URI '%s' for ios_assetsrc", uri);
    return FALSE;
  }

  return gst_ios_asset_src_set_uri (src, uri, err);
}

static void
gst_ios_asset_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
{
  GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;

  iface->get_type = gst_ios_asset_src_uri_get_type;
  iface->get_protocols = gst_ios_asset_src_uri_get_protocols;
  iface->get_uri = gst_ios_asset_src_uri_get_uri;
  iface->set_uri = gst_ios_asset_src_uri_set_uri;
}


@implementation GstAssetsLibrary

@synthesize asset;
@synthesize result;

- (id) init
{
  self = [super init];

  return self;
}

- (ALAssetRepresentation *) assetForURLSync:(NSURL*) uri
{
  dispatch_semaphore_t sema = dispatch_semaphore_create(0);
  dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

  dispatch_async(queue, ^{
    [self assetForURL:uri resultBlock:
        ^(ALAsset *myasset)
        {
          self.asset = myasset;
          self.result = [myasset defaultRepresentation];

          dispatch_semaphore_signal(sema);
        }
      failureBlock:
        ^(NSError *myerror)
        {
          self.result = nil;
          dispatch_semaphore_signal(sema);
        }
    ];
  });

  dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
  dispatch_release(sema);

  return self.result;
}
@end
