/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *                    2000 Wim Taymans <wtay@chello.be>
 *
 * gstpluginfeature.c: Abstract base class for all plugin features
 *
 * 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.
 */

/**
 * SECTION:gstpluginfeature
 * @short_description: Base class for contents of a GstPlugin
 * @see_also: #GstPlugin
 *
 * This is a base class for anything that can be added to a #GstPlugin.
 */

#include "gst_private.h"

#include "gstpluginfeature.h"
#include "gstplugin.h"
#include "gstregistry.h"
#include "gstinfo.h"

#include <stdio.h>
#include <string.h>

#define GST_CAT_DEFAULT GST_CAT_PLUGIN_LOADING

static void gst_plugin_feature_finalize (GObject * object);

/* static guint gst_plugin_feature_signals[LAST_SIGNAL] = { 0 }; */

G_DEFINE_ABSTRACT_TYPE (GstPluginFeature, gst_plugin_feature, GST_TYPE_OBJECT);

static void
gst_plugin_feature_class_init (GstPluginFeatureClass * klass)
{
  G_OBJECT_CLASS (klass)->finalize = gst_plugin_feature_finalize;
}

static void
gst_plugin_feature_init (GstPluginFeature * feature)
{
  /* do nothing, needed because of G_DEFINE_TYPE */
}

static void
gst_plugin_feature_finalize (GObject * object)
{
  GstPluginFeature *feature = GST_PLUGIN_FEATURE_CAST (object);

  GST_DEBUG ("finalizing feature %p: '%s'", feature, GST_OBJECT_NAME (feature));

  if (feature->plugin != NULL) {
    g_object_remove_weak_pointer ((GObject *) feature->plugin,
        (gpointer *) & feature->plugin);
  }

  G_OBJECT_CLASS (gst_plugin_feature_parent_class)->finalize (object);
}

/**
 * gst_plugin_feature_load:
 * @feature: (transfer none): the plugin feature to check
 *
 * Loads the plugin containing @feature if it's not already loaded. @feature is
 * unaffected; use the return value instead.
 *
 * Normally this function is used like this:
 * |[<!-- language="C" -->
 * GstPluginFeature *loaded_feature;
 *
 * loaded_feature = gst_plugin_feature_load (feature);
 * // presumably, we're no longer interested in the potentially-unloaded feature
 * gst_object_unref (feature);
 * feature = loaded_feature;
 * ]|
 *
 * Returns: (transfer full) (nullable): a reference to the loaded
 * feature, or %NULL on error
 */
GstPluginFeature *
gst_plugin_feature_load (GstPluginFeature * feature)
{
  GstPlugin *plugin;
  GstPluginFeature *real_feature;

  g_return_val_if_fail (feature != NULL, FALSE);
  g_return_val_if_fail (GST_IS_PLUGIN_FEATURE (feature), FALSE);

  GST_DEBUG ("loading plugin for feature %p; '%s'", feature,
      GST_OBJECT_NAME (feature));
  if (feature->loaded)
    return gst_object_ref (feature);

  GST_DEBUG ("loading plugin %s", feature->plugin_name);
  plugin = gst_plugin_load_by_name (feature->plugin_name);
  if (!plugin)
    goto load_failed;

  GST_DEBUG ("loaded plugin %s", feature->plugin_name);
  gst_object_unref (plugin);

  real_feature = gst_registry_lookup_feature (gst_registry_get (),
      GST_OBJECT_NAME (feature));

  if (real_feature == NULL)
    goto disappeared;
  else if (!real_feature->loaded)
    goto not_found;

  return real_feature;

  /* ERRORS */
load_failed:
  {
    GST_WARNING ("Failed to load plugin containing feature '%s'.",
        GST_OBJECT_NAME (feature));
    return NULL;
  }
disappeared:
  {
    GST_INFO
        ("Loaded plugin containing feature '%s', but feature disappeared.",
        GST_OBJECT_NAME (feature));
    return NULL;
  }
not_found:
  {
    GST_INFO ("Tried to load plugin containing feature '%s', but feature was "
        "not found.", GST_OBJECT_NAME (real_feature));
    return NULL;
  }
}

/**
 * gst_plugin_feature_set_rank:
 * @feature: feature to rank
 * @rank: rank value - higher number means more priority rank
 *
 * Specifies a rank for a plugin feature, so that autoplugging uses
 * the most appropriate feature.
 */
void
gst_plugin_feature_set_rank (GstPluginFeature * feature, guint rank)
{
  g_return_if_fail (feature != NULL);
  g_return_if_fail (GST_IS_PLUGIN_FEATURE (feature));

  feature->rank = rank;
}

/**
 * gst_plugin_feature_get_rank:
 * @feature: a feature
 *
 * Gets the rank of a plugin feature.
 *
 * Returns: The rank of the feature
 */
guint
gst_plugin_feature_get_rank (GstPluginFeature * feature)
{
  g_return_val_if_fail (GST_IS_PLUGIN_FEATURE (feature), GST_RANK_NONE);

  return feature->rank;
}

/**
 * gst_plugin_feature_get_plugin:
 * @feature: a feature
 *
 * Get the plugin that provides this feature.
 *
 * Returns: (transfer full) (nullable): the plugin that provides this
 *     feature, or %NULL.  Unref with gst_object_unref() when no
 *     longer needed.
 */
GstPlugin *
gst_plugin_feature_get_plugin (GstPluginFeature * feature)
{
  g_return_val_if_fail (GST_IS_PLUGIN_FEATURE (feature), NULL);

  if (feature->plugin == NULL)
    return NULL;

  return (GstPlugin *) gst_object_ref (feature->plugin);
}

/**
 * gst_plugin_feature_get_plugin_name:
 * @feature: a feature
 *
 * Get the name of the plugin that provides this feature.
 *
 * Returns: (nullable): the name of the plugin that provides this
 *     feature, or %NULL if the feature is not associated with a
 *     plugin.
 *
 * Since: 1.2
 */
const gchar *
gst_plugin_feature_get_plugin_name (GstPluginFeature * feature)
{
  g_return_val_if_fail (GST_IS_PLUGIN_FEATURE (feature), NULL);

  if (feature->plugin == NULL)
    return NULL;

  return gst_plugin_get_name (feature->plugin);
}

/**
 * gst_plugin_feature_list_free:
 * @list: (transfer full) (element-type Gst.PluginFeature): list
 *     of #GstPluginFeature
 *
 * Unrefs each member of @list, then frees the list.
 */
void
gst_plugin_feature_list_free (GList * list)
{
  GList *g;

  for (g = list; g; g = g->next) {
    GstPluginFeature *feature = GST_PLUGIN_FEATURE_CAST (g->data);

    gst_object_unref (feature);
  }
  g_list_free (list);
}

/**
 * gst_plugin_feature_list_copy:
 * @list: (transfer none) (element-type Gst.PluginFeature): list
 *     of #GstPluginFeature
 *
 * Copies the list of features. Caller should call @gst_plugin_feature_list_free
 * when done with the list.
 *
 * Returns: (transfer full) (element-type Gst.PluginFeature): a copy of @list,
 *     with each feature's reference count incremented.
 */
GList *
gst_plugin_feature_list_copy (GList * list)
{
  GList *new_list = NULL;

  if (G_LIKELY (list)) {
    GList *last;

    new_list = g_list_alloc ();
    new_list->data = gst_object_ref (list->data);
    new_list->prev = NULL;
    last = new_list;
    list = list->next;
    while (list) {
      last->next = g_list_alloc ();
      last->next->prev = last;
      last = last->next;
      last->data = gst_object_ref (list->data);
      list = list->next;
    }
    last->next = NULL;
  }

  return new_list;
}

/**
 * gst_plugin_feature_list_debug:
 * @list: (transfer none) (element-type Gst.PluginFeature): a #GList of
 *     plugin features
 *
 * Debug the plugin feature names in @list.
 */
void
gst_plugin_feature_list_debug (GList * list)
{
#ifndef GST_DISABLE_GST_DEBUG
  while (list) {
    GST_DEBUG ("%s",
        gst_plugin_feature_get_name ((GstPluginFeature *) list->data));
    list = list->next;
  }
#endif
}

/**
 * gst_plugin_feature_check_version:
 * @feature: a feature
 * @min_major: minimum required major version
 * @min_minor: minimum required minor version
 * @min_micro: minimum required micro version
 *
 * Checks whether the given plugin feature is at least
 *  the required version
 *
 * Returns: %TRUE if the plugin feature has at least
 *  the required version, otherwise %FALSE.
 */
gboolean
gst_plugin_feature_check_version (GstPluginFeature * feature,
    guint min_major, guint min_minor, guint min_micro)
{
  GstRegistry *registry;
  GstPlugin *plugin;
  gboolean ret = FALSE;

  g_return_val_if_fail (feature != NULL, FALSE);
  g_return_val_if_fail (GST_IS_PLUGIN_FEATURE (feature), FALSE);

  GST_DEBUG ("Looking up plugin '%s' containing plugin feature '%s'",
      feature->plugin_name, GST_OBJECT_NAME (feature));

  registry = gst_registry_get ();
  plugin = gst_registry_find_plugin (registry, feature->plugin_name);

  if (plugin) {
    const gchar *ver_str;
    guint major, minor, micro, nano;
    gint nscan;

    ver_str = gst_plugin_get_version (plugin);
    g_return_val_if_fail (ver_str != NULL, FALSE);

    nscan = sscanf (ver_str, "%u.%u.%u.%u", &major, &minor, &micro, &nano);
    GST_DEBUG ("version string '%s' parsed to %d values", ver_str, nscan);

    if (nscan >= 3) {
      if (major > min_major)
        ret = TRUE;
      else if (major < min_major)
        ret = FALSE;
      else if (minor > min_minor)
        ret = TRUE;
      else if (minor < min_minor)
        ret = FALSE;
      else if (micro > min_micro)
        ret = TRUE;
      /* micro is 1 smaller but we have a nano version, this is the upcoming
       * release of the requested version and we're ok then */
      else if (nscan == 4 && nano > 0 && (micro + 1 == min_micro))
        ret = TRUE;
      else
        ret = (micro == min_micro);

      GST_DEBUG ("Checking whether %u.%u.%u >= %u.%u.%u? %s", major, minor,
          micro, min_major, min_minor, min_micro, (ret) ? "yes" : "no");
    } else {
      GST_WARNING ("Could not parse version string '%s' of plugin '%s'",
          ver_str, feature->plugin_name);
    }

    gst_object_unref (plugin);
  } else {
    GST_DEBUG ("Could not find plugin '%s'", feature->plugin_name);
  }

  return ret;
}

/**
 * gst_plugin_feature_rank_compare_func:
 * @p1: a #GstPluginFeature
 * @p2: a #GstPluginFeature
 *
 * Compares the two given #GstPluginFeature instances. This function can be
 * used as a #GCompareFunc when sorting by rank and then by name.
 *
 * Returns: negative value if the rank of p1 > the rank of p2 or the ranks are
 * equal but the name of p1 comes before the name of p2; zero if the rank
 * and names are equal; positive value if the rank of p1 < the rank of p2 or the
 * ranks are equal but the name of p2 comes before the name of p1
 */
gint
gst_plugin_feature_rank_compare_func (gconstpointer p1, gconstpointer p2)
{
  GstPluginFeature *f1, *f2;
  gint diff;

  f1 = (GstPluginFeature *) p1;
  f2 = (GstPluginFeature *) p2;

  diff = f2->rank - f1->rank;
  if (diff != 0)
    return diff;

  diff = strcmp (GST_OBJECT_NAME (f1), GST_OBJECT_NAME (f2));

  return diff;
}
