/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright (C) 2006-2007 Red Hat, Inc.
 *
 * 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, see <http://www.gnu.org/licenses/>.
 *
 * Author: Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"
#include <string.h>
#include "gvfs.h"
#include "glib-private.h"
#include "glocalvfs.h"
#include "gresourcefile.h"
#include "giomodule-priv.h"
#include "glibintl.h"


/**
 * SECTION:gvfs
 * @short_description: Virtual File System
 * @include: gio/gio.h
 *
 * Entry point for using GIO functionality.
 *
 */

static GRWLock additional_schemes_lock;

typedef struct _GVfsPrivate {
  GHashTable *additional_schemes;
  char const **supported_schemes;
} GVfsPrivate;

typedef struct {
  GVfsFileLookupFunc uri_func;
  gpointer uri_data;
  GDestroyNotify uri_destroy;

  GVfsFileLookupFunc parse_name_func;
  gpointer parse_name_data;
  GDestroyNotify parse_name_destroy;
} GVfsURISchemeData;

G_DEFINE_TYPE_WITH_PRIVATE (GVfs, g_vfs, G_TYPE_OBJECT)

static void
g_vfs_dispose (GObject *object)
{
  GVfs *vfs = G_VFS (object);
  GVfsPrivate *priv = g_vfs_get_instance_private (vfs);

  g_clear_pointer (&priv->additional_schemes, g_hash_table_destroy);
  g_clear_pointer (&priv->supported_schemes, g_free);

  G_OBJECT_CLASS (g_vfs_parent_class)->dispose (object);
}

static void
g_vfs_class_init (GVfsClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  object_class->dispose = g_vfs_dispose;
}

static GFile *
resource_parse_name (GVfs       *vfs,
                     const char *parse_name,
                     gpointer    user_data)
{
  if (g_str_has_prefix (parse_name, "resource:"))
    return _g_resource_file_new (parse_name);

  return NULL;
}

static GFile *
resource_get_file_for_uri (GVfs       *vfs,
                           const char *uri,
                           gpointer    user_data)
{
  return _g_resource_file_new (uri);
}

static void
g_vfs_uri_lookup_func_closure_free (gpointer data)
{
  GVfsURISchemeData *closure = data;

  if (closure->uri_destroy)
    closure->uri_destroy (closure->uri_data);
  if (closure->parse_name_destroy)
    closure->parse_name_destroy (closure->parse_name_data);

  g_free (closure);
}

static void
g_vfs_init (GVfs *vfs)
{
  GVfsPrivate *priv = g_vfs_get_instance_private (vfs);
  priv->additional_schemes =
    g_hash_table_new_full (g_str_hash, g_str_equal,
                           g_free, g_vfs_uri_lookup_func_closure_free);

  g_vfs_register_uri_scheme (vfs, "resource",
                             resource_get_file_for_uri, NULL, NULL,
                             resource_parse_name, NULL, NULL);
}

/**
 * g_vfs_is_active:
 * @vfs: a #GVfs.
 *
 * Checks if the VFS is active.
 *
 * Returns: %TRUE if construction of the @vfs was successful
 *     and it is now active.
 */
gboolean
g_vfs_is_active (GVfs *vfs)
{
  GVfsClass *class;

  g_return_val_if_fail (G_IS_VFS (vfs), FALSE);

  class = G_VFS_GET_CLASS (vfs);

  return (* class->is_active) (vfs);
}


/**
 * g_vfs_get_file_for_path:
 * @vfs: a #GVfs.
 * @path: a string containing a VFS path.
 *
 * Gets a #GFile for @path.
 *
 * Returns: (transfer full): a #GFile.
 *     Free the returned object with g_object_unref().
 */
GFile *
g_vfs_get_file_for_path (GVfs       *vfs,
                         const char *path)
{
  GVfsClass *class;
 
  g_return_val_if_fail (G_IS_VFS (vfs), NULL);
  g_return_val_if_fail (path != NULL, NULL);

  class = G_VFS_GET_CLASS (vfs);

  return (* class->get_file_for_path) (vfs, path);
}

static GFile *
parse_name_internal (GVfs       *vfs,
                     const char *parse_name)
{
  GVfsPrivate *priv = g_vfs_get_instance_private (vfs);
  GHashTableIter iter;
  GVfsURISchemeData *closure;
  GFile *ret = NULL;

  g_rw_lock_reader_lock (&additional_schemes_lock);
  g_hash_table_iter_init (&iter, priv->additional_schemes);

  while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &closure))
    {
      ret = closure->parse_name_func (vfs, parse_name,
                                      closure->parse_name_data);

      if (ret)
        break;
    }

  g_rw_lock_reader_unlock (&additional_schemes_lock);

  return ret;
}

static GFile *
get_file_for_uri_internal (GVfs       *vfs,
                           const char *uri)
{
  GVfsPrivate *priv = g_vfs_get_instance_private (vfs);
  GFile *ret = NULL;
  char *scheme;
  GVfsURISchemeData *closure;

  scheme = g_uri_parse_scheme (uri);
  if (scheme == NULL)
    return NULL;

  g_rw_lock_reader_lock (&additional_schemes_lock);
  closure = g_hash_table_lookup (priv->additional_schemes, scheme);

  if (closure)
    ret = closure->uri_func (vfs, uri, closure->uri_data);

  g_rw_lock_reader_unlock (&additional_schemes_lock);

  g_free (scheme);
  return ret;
}

/**
 * g_vfs_get_file_for_uri:
 * @vfs: a#GVfs.
 * @uri: a string containing a URI
 *
 * Gets a #GFile for @uri.
 *
 * This operation never fails, but the returned object
 * might not support any I/O operation if the URI
 * is malformed or if the URI scheme is not supported.
 *
 * Returns: (transfer full): a #GFile.
 *     Free the returned object with g_object_unref().
 */
GFile *
g_vfs_get_file_for_uri (GVfs       *vfs,
                        const char *uri)
{
  GVfsClass *class;
  GFile *ret = NULL;
 
  g_return_val_if_fail (G_IS_VFS (vfs), NULL);
  g_return_val_if_fail (uri != NULL, NULL);

  class = G_VFS_GET_CLASS (vfs);

  ret = get_file_for_uri_internal (vfs, uri);
  if (!ret)
    ret = (* class->get_file_for_uri) (vfs, uri);

  g_assert (ret != NULL);

  return g_steal_pointer (&ret);
}

/**
 * g_vfs_get_supported_uri_schemes:
 * @vfs: a #GVfs.
 *
 * Gets a list of URI schemes supported by @vfs.
 *
 * Returns: (transfer none): a %NULL-terminated array of strings.
 *     The returned array belongs to GIO and must
 *     not be freed or modified.
 */
const gchar * const *
g_vfs_get_supported_uri_schemes (GVfs *vfs)
{
  GVfsPrivate *priv;

  g_return_val_if_fail (G_IS_VFS (vfs), NULL);

  priv = g_vfs_get_instance_private (vfs);

  if (!priv->supported_schemes)
    {
      GVfsClass *class;
      const char * const *default_schemes;
      const char *additional_scheme;
      GPtrArray *supported_schemes;
      GHashTableIter iter;

      class = G_VFS_GET_CLASS (vfs);

      default_schemes = (* class->get_supported_uri_schemes) (vfs);
      supported_schemes = g_ptr_array_new ();

      for (; default_schemes && *default_schemes; default_schemes++)
        g_ptr_array_add (supported_schemes, (gpointer) *default_schemes);

      g_rw_lock_reader_lock (&additional_schemes_lock);
      g_hash_table_iter_init (&iter, priv->additional_schemes);

      while (g_hash_table_iter_next
             (&iter, (gpointer *) &additional_scheme, NULL))
        g_ptr_array_add (supported_schemes, (gpointer) additional_scheme);

      g_rw_lock_reader_unlock (&additional_schemes_lock);

      g_ptr_array_add (supported_schemes, NULL);

      g_free (priv->supported_schemes);
      priv->supported_schemes =
        (char const **) g_ptr_array_free (supported_schemes, FALSE);
    }

  return priv->supported_schemes;
}

/**
 * g_vfs_parse_name:
 * @vfs: a #GVfs.
 * @parse_name: a string to be parsed by the VFS module.
 *
 * This operation never fails, but the returned object might
 * not support any I/O operations if the @parse_name cannot
 * be parsed by the #GVfs module.
 *
 * Returns: (transfer full): a #GFile for the given @parse_name.
 *     Free the returned object with g_object_unref().
 */
GFile *
g_vfs_parse_name (GVfs       *vfs,
                  const char *parse_name)
{
  GVfsClass *class;
  GFile *ret;

  g_return_val_if_fail (G_IS_VFS (vfs), NULL);
  g_return_val_if_fail (parse_name != NULL, NULL);

  class = G_VFS_GET_CLASS (vfs);

  ret = parse_name_internal (vfs, parse_name);
  if (ret)
    return ret;

  return (* class->parse_name) (vfs, parse_name);
}

static GVfs *vfs_default_singleton = NULL;  /* (owned) (atomic) */

/**
 * g_vfs_get_default:
 *
 * Gets the default #GVfs for the system.
 *
 * Returns: (not nullable) (transfer none): a #GVfs, which will be the local
 *     file system #GVfs if no other implementation is available.
 */
GVfs *
g_vfs_get_default (void)
{
  if (GLIB_PRIVATE_CALL (g_check_setuid) ())
    return g_vfs_get_local ();

  if (g_once_init_enter (&vfs_default_singleton))
    {
      GVfs *singleton;

      singleton = _g_io_module_get_default (G_VFS_EXTENSION_POINT_NAME,
                                            "GIO_USE_VFS",
                                            (GIOModuleVerifyFunc) g_vfs_is_active);

      g_once_init_leave (&vfs_default_singleton, singleton);
    }

  return vfs_default_singleton;
}

/**
 * g_vfs_get_local:
 *
 * Gets the local #GVfs for the system.
 *
 * Returns: (transfer none): a #GVfs.
 */
GVfs *
g_vfs_get_local (void)
{
  static gsize vfs = 0;

  if (g_once_init_enter (&vfs))
    g_once_init_leave (&vfs, (gsize)_g_local_vfs_new ());

  return G_VFS (vfs);
}

/**
 * g_vfs_register_uri_scheme:
 * @vfs: a #GVfs
 * @scheme: an URI scheme, e.g. "http"
 * @uri_func: (scope notified) (nullable): a #GVfsFileLookupFunc
 * @uri_data: (nullable): custom data passed to be passed to @uri_func, or %NULL
 * @uri_destroy: (nullable): function to be called when unregistering the
 *     URI scheme, or when @vfs is disposed, to free the resources used
 *     by the URI lookup function
 * @parse_name_func: (scope notified) (nullable): a #GVfsFileLookupFunc
 * @parse_name_data: (nullable): custom data passed to be passed to
 *     @parse_name_func, or %NULL
 * @parse_name_destroy: (nullable): function to be called when unregistering the
 *     URI scheme, or when @vfs is disposed, to free the resources used
 *     by the parse name lookup function
 *
 * Registers @uri_func and @parse_name_func as the #GFile URI and parse name
 * lookup functions for URIs with a scheme matching @scheme.
 * Note that @scheme is registered only within the running application, as
 * opposed to desktop-wide as it happens with GVfs backends.
 *
 * When a #GFile is requested with an URI containing @scheme (e.g. through
 * g_file_new_for_uri()), @uri_func will be called to allow a custom
 * constructor. The implementation of @uri_func should not be blocking, and
 * must not call g_vfs_register_uri_scheme() or g_vfs_unregister_uri_scheme().
 *
 * When g_file_parse_name() is called with a parse name obtained from such file,
 * @parse_name_func will be called to allow the #GFile to be created again. In
 * that case, it's responsibility of @parse_name_func to make sure the parse
 * name matches what the custom #GFile implementation returned when
 * g_file_get_parse_name() was previously called. The implementation of
 * @parse_name_func should not be blocking, and must not call
 * g_vfs_register_uri_scheme() or g_vfs_unregister_uri_scheme().
 *
 * It's an error to call this function twice with the same scheme. To unregister
 * a custom URI scheme, use g_vfs_unregister_uri_scheme().
 *
 * Returns: %TRUE if @scheme was successfully registered, or %FALSE if a handler
 *     for @scheme already exists.
 *
 * Since: 2.50
 */
gboolean
g_vfs_register_uri_scheme (GVfs              *vfs,
                           const char        *scheme,
                           GVfsFileLookupFunc uri_func,
                           gpointer           uri_data,
                           GDestroyNotify     uri_destroy,
                           GVfsFileLookupFunc parse_name_func,
                           gpointer           parse_name_data,
                           GDestroyNotify     parse_name_destroy)
{
  GVfsPrivate *priv;
  GVfsURISchemeData *closure;

  g_return_val_if_fail (G_IS_VFS (vfs), FALSE);
  g_return_val_if_fail (scheme != NULL, FALSE);

  priv = g_vfs_get_instance_private (vfs);

  g_rw_lock_reader_lock (&additional_schemes_lock);
  closure = g_hash_table_lookup (priv->additional_schemes, scheme);
  g_rw_lock_reader_unlock (&additional_schemes_lock);

  if (closure != NULL)
    return FALSE;

  closure = g_new0 (GVfsURISchemeData, 1);
  closure->uri_func = uri_func;
  closure->uri_data = uri_data;
  closure->uri_destroy = uri_destroy;
  closure->parse_name_func = parse_name_func;
  closure->parse_name_data = parse_name_data;
  closure->parse_name_destroy = parse_name_destroy;

  g_rw_lock_writer_lock (&additional_schemes_lock);
  g_hash_table_insert (priv->additional_schemes, g_strdup (scheme), closure);
  g_rw_lock_writer_unlock (&additional_schemes_lock);

  /* Invalidate supported schemes */
  g_clear_pointer (&priv->supported_schemes, g_free);

  return TRUE;
}

/**
 * g_vfs_unregister_uri_scheme:
 * @vfs: a #GVfs
 * @scheme: an URI scheme, e.g. "http"
 *
 * Unregisters the URI handler for @scheme previously registered with
 * g_vfs_register_uri_scheme().
 *
 * Returns: %TRUE if @scheme was successfully unregistered, or %FALSE if a
 *     handler for @scheme does not exist.
 *
 * Since: 2.50
 */
gboolean
g_vfs_unregister_uri_scheme (GVfs       *vfs,
                             const char *scheme)
{
  GVfsPrivate *priv;
  gboolean res;

  g_return_val_if_fail (G_IS_VFS (vfs), FALSE);
  g_return_val_if_fail (scheme != NULL, FALSE);

  priv = g_vfs_get_instance_private (vfs);

  g_rw_lock_writer_lock (&additional_schemes_lock);
  res = g_hash_table_remove (priv->additional_schemes, scheme);
  g_rw_lock_writer_unlock (&additional_schemes_lock);

  if (res)
    {
      /* Invalidate supported schemes */
      g_clear_pointer (&priv->supported_schemes, g_free);

      return TRUE;
    }

  return FALSE;
}
