/* 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>
 *         David Zeuthen <davidz@redhat.com>
 */

#include "config.h"
#include "gmount.h"
#include "gvolume.h"
#include "gthemedicon.h"
#include "gasyncresult.h"
#include "gtask.h"
#include "gioerror.h"
#include "glibintl.h"


/**
 * SECTION:gvolume
 * @short_description: Volume management
 * @include: gio/gio.h
 * 
 * The #GVolume interface represents user-visible objects that can be
 * mounted. Note, when porting from GnomeVFS, #GVolume is the moral
 * equivalent of #GnomeVFSDrive.
 *
 * Mounting a #GVolume instance is an asynchronous operation. For more
 * information about asynchronous operations, see #GAsyncResult and
 * #GTask. To mount a #GVolume, first call g_volume_mount() with (at
 * least) the #GVolume instance, optionally a #GMountOperation object
 * and a #GAsyncReadyCallback.
 *
 * Typically, one will only want to pass %NULL for the
 * #GMountOperation if automounting all volumes when a desktop session
 * starts since it's not desirable to put up a lot of dialogs asking
 * for credentials.
 *
 * The callback will be fired when the operation has resolved (either
 * with success or failure), and a #GAsyncResult instance will be
 * passed to the callback.  That callback should then call
 * g_volume_mount_finish() with the #GVolume instance and the
 * #GAsyncResult data to see if the operation was completed
 * successfully.  If an @error is present when g_volume_mount_finish()
 * is called, then it will be filled with any error information.
 *
 * ## Volume Identifiers # {#volume-identifier}
 *
 * It is sometimes necessary to directly access the underlying
 * operating system object behind a volume (e.g. for passing a volume
 * to an application via the commandline). For this purpose, GIO
 * allows to obtain an 'identifier' for the volume. There can be
 * different kinds of identifiers, such as Hal UDIs, filesystem labels,
 * traditional Unix devices (e.g. `/dev/sda2`), UUIDs. GIO uses predefined
 * strings as names for the different kinds of identifiers:
 * #G_VOLUME_IDENTIFIER_KIND_UUID, #G_VOLUME_IDENTIFIER_KIND_LABEL, etc.
 * Use g_volume_get_identifier() to obtain an identifier for a volume.
 *
 *
 * Note that #G_VOLUME_IDENTIFIER_KIND_HAL_UDI will only be available
 * when the gvfs hal volume monitor is in use. Other volume monitors
 * will generally be able to provide the #G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE
 * identifier, which can be used to obtain a hal device by means of
 * libhal_manager_find_device_string_match().
 */

typedef GVolumeIface GVolumeInterface;
G_DEFINE_INTERFACE(GVolume, g_volume, G_TYPE_OBJECT)

static void
g_volume_default_init (GVolumeInterface *iface)
{
  /**
   * GVolume::changed:
   * 
   * Emitted when the volume has been changed.
   */
  g_signal_new (I_("changed"),
		G_TYPE_VOLUME,
		G_SIGNAL_RUN_LAST,
		G_STRUCT_OFFSET (GVolumeIface, changed),
		NULL, NULL,
		NULL,
		G_TYPE_NONE, 0);

  /**
   * GVolume::removed:
   * 
   * This signal is emitted when the #GVolume have been removed. If
   * the recipient is holding references to the object they should
   * release them so the object can be finalized.
   */
  g_signal_new (I_("removed"),
		G_TYPE_VOLUME,
		G_SIGNAL_RUN_LAST,
		G_STRUCT_OFFSET (GVolumeIface, removed),
		NULL, NULL,
		NULL,
		G_TYPE_NONE, 0);
}

/**
 * g_volume_get_name:
 * @volume: a #GVolume
 * 
 * Gets the name of @volume.
 * 
 * Returns: the name for the given @volume. The returned string should 
 *     be freed with g_free() when no longer needed.
 */
char *
g_volume_get_name (GVolume *volume)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), NULL);

  iface = G_VOLUME_GET_IFACE (volume);

  return (* iface->get_name) (volume);
}

/**
 * g_volume_get_icon:
 * @volume: a #GVolume
 * 
 * Gets the icon for @volume.
 * 
 * Returns: (transfer full): a #GIcon.
 *     The returned object should be unreffed with g_object_unref()
 *     when no longer needed.
 */
GIcon *
g_volume_get_icon (GVolume *volume)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), NULL);

  iface = G_VOLUME_GET_IFACE (volume);

  return (* iface->get_icon) (volume);
}

/**
 * g_volume_get_symbolic_icon:
 * @volume: a #GVolume
 * 
 * Gets the symbolic icon for @volume.
 * 
 * Returns: (transfer full): a #GIcon.
 *     The returned object should be unreffed with g_object_unref()
 *     when no longer needed.
 *
 * Since: 2.34
 */
GIcon *
g_volume_get_symbolic_icon (GVolume *volume)
{
  GVolumeIface *iface;
  GIcon *ret;

  g_return_val_if_fail (G_IS_VOLUME (volume), NULL);

  iface = G_VOLUME_GET_IFACE (volume);

  if (iface->get_symbolic_icon != NULL)
    ret = iface->get_symbolic_icon (volume);
  else
    ret = g_themed_icon_new_with_default_fallbacks ("folder-remote-symbolic");

  return ret;

}

/**
 * g_volume_get_uuid:
 * @volume: a #GVolume
 * 
 * Gets the UUID for the @volume. The reference is typically based on
 * the file system UUID for the volume in question and should be
 * considered an opaque string. Returns %NULL if there is no UUID
 * available.
 * 
 * Returns: (nullable) (transfer full): the UUID for @volume or %NULL if no UUID
 *     can be computed.
 *     The returned string should be freed with g_free() 
 *     when no longer needed.
 */
char *
g_volume_get_uuid (GVolume *volume)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), NULL);

  iface = G_VOLUME_GET_IFACE (volume);

  return (* iface->get_uuid) (volume);
}
  
/**
 * g_volume_get_drive:
 * @volume: a #GVolume
 * 
 * Gets the drive for the @volume.
 *
 * Returns: (transfer full) (nullable): a #GDrive or %NULL if @volume is not
 *     associated with a drive. The returned object should be unreffed
 *     with g_object_unref() when no longer needed.
 */
GDrive *
g_volume_get_drive (GVolume *volume)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), NULL);

  iface = G_VOLUME_GET_IFACE (volume);

  return (* iface->get_drive) (volume);
}

/**
 * g_volume_get_mount:
 * @volume: a #GVolume
 * 
 * Gets the mount for the @volume.
 *
 * Returns: (transfer full) (nullable): a #GMount or %NULL if @volume isn't mounted.
 *     The returned object should be unreffed with g_object_unref()
 *     when no longer needed.
 */
GMount *
g_volume_get_mount (GVolume *volume)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), NULL);

  iface = G_VOLUME_GET_IFACE (volume);

  return (* iface->get_mount) (volume);
}


/**
 * g_volume_can_mount:
 * @volume: a #GVolume
 * 
 * Checks if a volume can be mounted.
 * 
 * Returns: %TRUE if the @volume can be mounted. %FALSE otherwise
 */
gboolean
g_volume_can_mount (GVolume *volume)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);

  iface = G_VOLUME_GET_IFACE (volume);

  if (iface->can_mount == NULL)
    return FALSE;

  return (* iface->can_mount) (volume);
}

/**
 * g_volume_can_eject:
 * @volume: a #GVolume
 * 
 * Checks if a volume can be ejected.
 * 
 * Returns: %TRUE if the @volume can be ejected. %FALSE otherwise
 */
gboolean
g_volume_can_eject (GVolume *volume)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);

  iface = G_VOLUME_GET_IFACE (volume);

  if (iface->can_eject == NULL)
    return FALSE;

  return (* iface->can_eject) (volume);
}

/**
 * g_volume_should_automount:
 * @volume: a #GVolume
 *
 * Returns whether the volume should be automatically mounted.
 * 
 * Returns: %TRUE if the volume should be automatically mounted
 */
gboolean
g_volume_should_automount (GVolume *volume)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);

  iface = G_VOLUME_GET_IFACE (volume);

  if (iface->should_automount == NULL)
    return FALSE;

  return (* iface->should_automount) (volume);
}


/**
 * g_volume_mount:
 * @volume: a #GVolume
 * @flags: flags affecting the operation
 * @mount_operation: (nullable): a #GMountOperation or %NULL to avoid user interaction
 * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore
 * @callback: (nullable): a #GAsyncReadyCallback, or %NULL
 * @user_data: user data that gets passed to @callback
 * 
 * Mounts a volume. This is an asynchronous operation, and is
 * finished by calling g_volume_mount_finish() with the @volume
 * and #GAsyncResult returned in the @callback.
 *
 * Virtual: mount_fn
 */
void
g_volume_mount (GVolume             *volume,
		GMountMountFlags     flags,
                GMountOperation     *mount_operation,
                GCancellable        *cancellable,
                GAsyncReadyCallback  callback,
                gpointer             user_data)
{
  GVolumeIface *iface;

  g_return_if_fail (G_IS_VOLUME (volume));

  iface = G_VOLUME_GET_IFACE (volume);

  if (iface->mount_fn == NULL)
    {
      g_task_report_new_error (volume, callback, user_data,
                               g_volume_mount,
                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                               _("volume doesn’t implement mount"));
      return;
    }
  
  (* iface->mount_fn) (volume, flags, mount_operation, cancellable, callback, user_data);
}

/**
 * g_volume_mount_finish:
 * @volume: a #GVolume
 * @result: a #GAsyncResult
 * @error: a #GError location to store an error, or %NULL to ignore
 * 
 * Finishes mounting a volume. If any errors occurred during the operation,
 * @error will be set to contain the errors and %FALSE will be returned.
 *
 * If the mount operation succeeded, g_volume_get_mount() on @volume
 * is guaranteed to return the mount right after calling this
 * function; there's no need to listen for the 'mount-added' signal on
 * #GVolumeMonitor.
 * 
 * Returns: %TRUE, %FALSE if operation failed
 */
gboolean
g_volume_mount_finish (GVolume       *volume,
                       GAsyncResult  *result,
                       GError       **error)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);

  if (g_async_result_legacy_propagate_error (result, error))
    return FALSE;
  else if (g_async_result_is_tagged (result, g_volume_mount))
    return g_task_propagate_boolean (G_TASK (result), error);
  
  iface = G_VOLUME_GET_IFACE (volume);
  return (* iface->mount_finish) (volume, result, error);
}

/**
 * g_volume_eject:
 * @volume: a #GVolume
 * @flags: flags affecting the unmount if required for eject
 * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore
 * @callback: (nullable): a #GAsyncReadyCallback, or %NULL
 * @user_data: user data that gets passed to @callback
 * 
 * Ejects a volume. This is an asynchronous operation, and is
 * finished by calling g_volume_eject_finish() with the @volume
 * and #GAsyncResult returned in the @callback.
 *
 * Deprecated: 2.22: Use g_volume_eject_with_operation() instead.
 */
void
g_volume_eject (GVolume             *volume,
		GMountUnmountFlags   flags,
                GCancellable        *cancellable,
                GAsyncReadyCallback  callback,
                gpointer             user_data)
{
  GVolumeIface *iface;

  g_return_if_fail (G_IS_VOLUME (volume));

  iface = G_VOLUME_GET_IFACE (volume);

  if (iface->eject == NULL)
    {
      g_task_report_new_error (volume, callback, user_data,
                               g_volume_eject_with_operation,
                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                               _("volume doesn’t implement eject"));
      return;
    }
  
  (* iface->eject) (volume, flags, cancellable, callback, user_data);
}

/**
 * g_volume_eject_finish:
 * @volume: pointer to a #GVolume
 * @result: a #GAsyncResult
 * @error: a #GError location to store an error, or %NULL to ignore
 * 
 * Finishes ejecting a volume. If any errors occurred during the operation,
 * @error will be set to contain the errors and %FALSE will be returned.
 * 
 * Returns: %TRUE, %FALSE if operation failed
 *
 * Deprecated: 2.22: Use g_volume_eject_with_operation_finish() instead.
 **/
gboolean
g_volume_eject_finish (GVolume       *volume,
                       GAsyncResult  *result,
                       GError       **error)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);

  if (g_async_result_legacy_propagate_error (result, error))
    return FALSE;
  if (g_async_result_is_tagged (result, g_volume_eject_with_operation))
    return g_task_propagate_boolean (G_TASK (result), error);
  
  iface = G_VOLUME_GET_IFACE (volume);
  return (* iface->eject_finish) (volume, result, error);
}

/**
 * g_volume_eject_with_operation:
 * @volume: a #GVolume
 * @flags: flags affecting the unmount if required for eject
 * @mount_operation: (nullable): a #GMountOperation or %NULL to
 *     avoid user interaction
 * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore
 * @callback: (nullable): a #GAsyncReadyCallback, or %NULL
 * @user_data: user data passed to @callback
 *
 * Ejects a volume. This is an asynchronous operation, and is
 * finished by calling g_volume_eject_with_operation_finish() with the @volume
 * and #GAsyncResult data returned in the @callback.
 *
 * Since: 2.22
 **/
void
g_volume_eject_with_operation (GVolume              *volume,
                               GMountUnmountFlags   flags,
                               GMountOperation     *mount_operation,
                               GCancellable        *cancellable,
                               GAsyncReadyCallback  callback,
                               gpointer             user_data)
{
  GVolumeIface *iface;

  g_return_if_fail (G_IS_VOLUME (volume));

  iface = G_VOLUME_GET_IFACE (volume);

  if (iface->eject == NULL && iface->eject_with_operation == NULL)
    {
      g_task_report_new_error (volume, callback, user_data,
                               g_volume_eject_with_operation,
                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                               /* Translators: This is an error
                                * message for volume objects that
                                * don't implement any of eject or eject_with_operation. */
                               _("volume doesn’t implement eject or eject_with_operation"));
      return;
    }

  if (iface->eject_with_operation != NULL)
    (* iface->eject_with_operation) (volume, flags, mount_operation, cancellable, callback, user_data);
  else
    (* iface->eject) (volume, flags, cancellable, callback, user_data);
}

/**
 * g_volume_eject_with_operation_finish:
 * @volume: a #GVolume
 * @result: a #GAsyncResult
 * @error: a #GError location to store the error occurring, or %NULL
 *
 * Finishes ejecting a volume. If any errors occurred during the operation,
 * @error will be set to contain the errors and %FALSE will be returned.
 *
 * Returns: %TRUE if the volume was successfully ejected. %FALSE otherwise
 *
 * Since: 2.22
 **/
gboolean
g_volume_eject_with_operation_finish (GVolume        *volume,
                                      GAsyncResult  *result,
                                      GError       **error)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);

  if (g_async_result_legacy_propagate_error (result, error))
    return FALSE;
  else if (g_async_result_is_tagged (result, g_volume_eject_with_operation))
    return g_task_propagate_boolean (G_TASK (result), error);

  iface = G_VOLUME_GET_IFACE (volume);
  if (iface->eject_with_operation_finish != NULL)
    return (* iface->eject_with_operation_finish) (volume, result, error);
  else
    return (* iface->eject_finish) (volume, result, error);
}

/**
 * g_volume_get_identifier:
 * @volume: a #GVolume
 * @kind: the kind of identifier to return
 *
 * Gets the identifier of the given kind for @volume. 
 * See the [introduction][volume-identifier] for more
 * information about volume identifiers.
 *
 * Returns: (nullable) (transfer full): a newly allocated string containing the
 *     requested identifier, or %NULL if the #GVolume
 *     doesn't have this kind of identifier
 */
char *
g_volume_get_identifier (GVolume    *volume,
			 const char *kind)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
  g_return_val_if_fail (kind != NULL, NULL);

  iface = G_VOLUME_GET_IFACE (volume);

  if (iface->get_identifier == NULL)
    return NULL;
  
  return (* iface->get_identifier) (volume, kind);
}

/**
 * g_volume_enumerate_identifiers:
 * @volume: a #GVolume
 * 
 * Gets the kinds of [identifiers][volume-identifier] that @volume has.
 * Use g_volume_get_identifier() to obtain the identifiers themselves.
 *
 * Returns: (array zero-terminated=1) (transfer full): a %NULL-terminated array
 *   of strings containing kinds of identifiers. Use g_strfreev() to free.
 */
char **
g_volume_enumerate_identifiers (GVolume *volume)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
  iface = G_VOLUME_GET_IFACE (volume);

  if (iface->enumerate_identifiers == NULL)
    return NULL;
  
  return (* iface->enumerate_identifiers) (volume);
}

/**
 * g_volume_get_activation_root:
 * @volume: a #GVolume
 *
 * Gets the activation root for a #GVolume if it is known ahead of
 * mount time. Returns %NULL otherwise. If not %NULL and if @volume
 * is mounted, then the result of g_mount_get_root() on the
 * #GMount object obtained from g_volume_get_mount() will always
 * either be equal or a prefix of what this function returns. In
 * other words, in code
 *
 * |[<!-- language="C" -->
 *   GMount *mount;
 *   GFile *mount_root
 *   GFile *volume_activation_root;
 *
 *   mount = g_volume_get_mount (volume); // mounted, so never NULL
 *   mount_root = g_mount_get_root (mount);
 *   volume_activation_root = g_volume_get_activation_root (volume); // assume not NULL
 * ]|
 * then the expression
 * |[<!-- language="C" -->
 *   (g_file_has_prefix (volume_activation_root, mount_root) ||
 *    g_file_equal (volume_activation_root, mount_root))
 * ]|
 * will always be %TRUE.
 *
 * Activation roots are typically used in #GVolumeMonitor
 * implementations to find the underlying mount to shadow, see
 * g_mount_is_shadowed() for more details.
 *
 * Returns: (nullable) (transfer full): the activation root of @volume
 *     or %NULL. Use g_object_unref() to free.
 *
 * Since: 2.18
 */
GFile *
g_volume_get_activation_root (GVolume *volume)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
  iface = G_VOLUME_GET_IFACE (volume);

  if (iface->get_activation_root == NULL)
    return NULL;

  return (* iface->get_activation_root) (volume);
}

/**
 * g_volume_get_sort_key:
 * @volume: a #GVolume
 *
 * Gets the sort key for @volume, if any.
 *
 * Returns: (nullable): Sorting key for @volume or %NULL if no such key is available
 *
 * Since: 2.32
 */
const gchar *
g_volume_get_sort_key (GVolume *volume)
{
  const gchar *ret = NULL;
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), NULL);

  iface = G_VOLUME_GET_IFACE (volume);
  if (iface->get_sort_key != NULL)
    ret = iface->get_sort_key (volume);

  return ret;
}
