/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "nsISupports.idl"

interface nsIVariant;
interface nsIPropertyBag2;
interface nsIContentURIGrouper;
interface mozIStorageConnection;

[scriptable, uuid(746c7a02-f6c1-4869-b434-7c8b86e60e61)]
interface nsIContentPrefObserver : nsISupports
{
  /**
   * Called when a content pref is set to a different value.
   * 
   * @param    aGroup      the group to which the pref belongs, or null
   *                       if it's a global pref (applies to all sites)
   * @param    aName       the name of the pref that was set
   * @param    aValue      the new value of the pref
   */
  void onContentPrefSet(in AString aGroup, in AString aName, in nsIVariant aValue);

  /**
   * Called when a content pref is removed.
   * 
   * @param    aGroup      the group to which the pref belongs, or null
   *                       if it's a global pref (applies to all sites)
   * @param    aName       the name of the pref that was removed
   */
  void onContentPrefRemoved(in AString aGroup, in AString aName);
};

[scriptable, function, uuid(c1b3d6df-5373-4606-8494-8bcf14a7fc62)]
interface nsIContentPrefCallback : nsISupports
{
  void onResult(in nsIVariant aResult);
};

[scriptable, uuid(0014e2b4-1bab-4946-9211-7d28fc8df4d7)]
interface nsIContentPrefService : nsISupports
{
  /**
   * Get a pref.
   *
   * Besides the regular string, integer, boolean, etc. values, this method
   * may return null (nsIDataType::VTYPE_EMPTY), which means the pref is set
   * to NULL in the database, as well as undefined (nsIDataType::VTYPE_VOID),
   * which means there is no record for this pref in the database.
   *
   * This method can be called from content processes in electrolysis builds.
   * We have a whitelist of values that can be read in such a way.
   *
   * @param    aGroup      the group for which to get the pref, as an nsIURI
   *                       from which the hostname will be used, a string
   *                       (typically in the format of a hostname), or null 
   *                       to get the global pref (applies to all sites)
   * @param    aName       the name of the pref to get
   * @param    aCallback   an optional nsIContentPrefCallback to receive the
   *                       result. If desired, JavaScript callers can instead
   *                       provide a function to call upon completion
   *
   * @returns  the value of the pref
   * @throws   NS_ERROR_ILLEGAL_VALUE if aGroup is not a string, nsIURI, or null
   * @throws   NS_ERROR_ILLEGAL_VALUE if aName is null or an empty string
   */
  nsIVariant getPref(in nsIVariant aGroup, in AString aName,
                     [optional] in nsIContentPrefCallback aCallback);

  /**
   * Set a pref.
   *
   * This method can be called from content processes in electrolysis builds.
   * We have a whitelist of values that can be set in such a way.
   *
   * @param    aGroup      the group for which to set the pref, as an nsIURI
   *                       from which the hostname will be used, a string
   *                       (typically in the format of a hostname), or null
   *                       to set the global pref (applies to all sites)
   * @param    aName       the name of the pref to set
   * @param    aValue      the new value of the pref
   * @throws   NS_ERROR_ILLEGAL_VALUE if aGroup is not a string, nsIURI, or null
   * @throws   NS_ERROR_ILLEGAL_VALUE if aName is null or an empty string
   */
  void setPref(in nsIVariant aGroup, in AString aName, in nsIVariant aValue);
  
  /**
   * Check whether or not a pref exists.
   *
   * @param    aGroup      the group for which to check for the pref, as an nsIURI
   *                       from which the hostname will be used, a string
   *                       (typically in the format of a hostname), or null
   *                       to check for the global pref (applies to all sites)
   * @param    aName       the name of the pref to check for
   * @throws   NS_ERROR_ILLEGAL_VALUE if aGroup is not a string, nsIURI, or null
   * @throws   NS_ERROR_ILLEGAL_VALUE if aName is null or an empty string
   */
  boolean hasPref(in nsIVariant aGroup, in AString aName);

  /**
   * Check whether or not the value of a pref (or its non-existance) is cached.
   *
   * @param    aGroup      the group for which to check for the pref, as an nsIURI
   *                       from which the hostname will be used, a string
   *                       (typically in the format of a hostname), or null
   *                       to check for the global pref (applies to all sites)
   * @param    aName       the name of the pref to check for
   * @throws   NS_ERROR_ILLEGAL_VALUE if aGroup is not a string, nsIURI, or null
   * @throws   NS_ERROR_ILLEGAL_VALUE if aName is null or an empty string
   */
  boolean hasCachedPref(in nsIVariant aGroup, in AString aName);

  /**
   * Remove a pref.
   *
   * @param    aGroup      the group for which to remove the pref, as an nsIURI
   *                       from which the hostname will be used, a string
   *                       (typically in the format of a hostname), or null
   *                       to remove the global pref (applies to all sites) 
   * @param    aName       the name of the pref to remove
   * @throws   NS_ERROR_ILLEGAL_VALUE if aGroup is not a string, nsIURI, or null
   * @throws   NS_ERROR_ILLEGAL_VALUE if aName is null or an empty string
   */
  void removePref(in nsIVariant aGroup, in AString aName);

  /**
   * Remove all grouped prefs.  Useful for removing references to the sites
   * the user has visited when the user clears their private data.
   */
  void removeGroupedPrefs();

  /**
   * Remove all prefs with the given name.
   *
   * @param    aName        the setting name for which to remove prefs
   * @throws   NS_ERROR_ILLEGAL_VALUE if aName is null or an empty string
   */
  void removePrefsByName(in AString aName);

  /**
   * Get the prefs that apply to the given site.
   *
   * @param    aGroup      the group for which to retrieve prefs, as an nsIURI
   *                       from which the hostname will be used, a string
   *                       (typically in the format of a hostname), or null
   *                       to get the global prefs (apply to all sites) 
   * 
   * @returns  a property bag of prefs
   * @throws   NS_ERROR_ILLEGAL_VALUE if aGroup is not a string, nsIURI, or null
   */
  nsIPropertyBag2 getPrefs(in nsIVariant aGroup);

  /**
   * Get the prefs with the given name.
   *
   * @param    aName        the setting name for which to retrieve prefs
   * 
   * @returns  a property bag of prefs
   * @throws   NS_ERROR_ILLEGAL_VALUE if aName is null or an empty string
   */
  nsIPropertyBag2 getPrefsByName(in AString aName);
  
  /**
   * Add an observer.
   * 
   * @param    aName       the setting to observe, or null to add
   *                       a generic observer that observes all settings
   * @param    aObserver   the observer to add
   */
  void addObserver(in AString aName, in nsIContentPrefObserver aObserver);
  
  /**
   * Remove an observer.
   *
   * @param    aName       the setting being observed, or null to remove
   *                       a generic observer that observes all settings
   * @param    aObserver   the observer to remove
   */
  void removeObserver(in AString aName, in nsIContentPrefObserver aObserver);

  /**
   * The component that the service uses to determine the groups to which
   * URIs belong.  By default this is the "hostname grouper", which groups
   * URIs by full hostname (a.k.a. site).
   */
  readonly attribute nsIContentURIGrouper grouper;

  /**
   * The database connection to the content preferences database.
   * Useful for accessing and manipulating preferences in ways that are caller-
   * specific or for which there is not yet a generic method, although generic
   * functionality useful to multiple callers should generally be added to this
   * unfrozen interface.  Also useful for testing the database creation
   * and migration code.
   */
  readonly attribute mozIStorageConnection DBConnection;
};

%{C++
// The contractID for the generic implementation built in to xpcom.
#define NS_CONTENT_PREF_SERVICE_CONTRACTID "@mozilla.org/content-pref/service;1"
%}
