/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Content Preferences (cpref).
 *
 * The Initial Developer of the Original Code is Mozilla.
 * Portions created by the Initial Developer are Copyright (C) 2006
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Myk Melez <myk@mozilla.org>
 *   Geoff Lankow <geoff@darktrojan.net>
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#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"
%}
