/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 the Extension Manager.
 *
 * The Initial Developer of the Original Code is Ben Goodger.
 * Portions created by the Initial Developer are Copyright (C) 2004
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *  Ben Goodger <ben@mozilla.org> (Google Inc.)
 *
 * 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 nsIFile;
interface nsIRDFDataSource;
interface nsIUpdateItem;
interface nsICommandLine;
interface nsISimpleEnumerator;
interface nsIDirectoryEnumerator;

/**
 * Interface representing a location where extensions, themes etc are 
 * installed.
 */
[scriptable, uuid(D3D4DADA-C6EB-11D9-A68F-001124787B2E)]
interface nsIInstallLocation : nsISupports
{
  /**
   * The string identifier of this Install Location
   */
  readonly attribute AString name;
  
  /**
   * An enumeration of nsIFiles for:
   * - locations that contain items
   * - potential dropped-in XPIs
   * Note: This enumeration resolves Text Links to the directories they
   *       refer to.
   */
  readonly attribute nsIDirectoryEnumerator itemLocations;

  /**
   * The file system location where items live. Items can be dropped in
   * at this location. Can be null for Install Locations that don't have
   * a file system presence. 
   * Note: This is a clone of the actual location which the caller can 
   *       modify freely.
   */
  readonly attribute nsIFile location;

  /**
   * Whether or not this Install Location is on an area of the file system
   * that could be restricted on a restricted-access account, regardless
   * of whether or not the location is restricted with the current user
   * privileges. 
   */
  readonly attribute boolean restricted;

  /**
   * Whether or not the user can write to the Install Location with the
   * current access privileges. This is different from restricted because
   * it's not whether or not the location *might* be restricted, it's 
   * whether or not it actually *is* restricted right now.
   */
  readonly attribute boolean canAccess;

  /**
   * Constants representing priority of some default Install Locations.
   * XXXben - priority ranking of user-level items vs. global-level items
   *          here is debatable. Should app-system-global trump 
   *          xre-system-user?
   * You should not use the exact values here, you should offset from
   * these values each time you create a new Install Location. Offsetting
   * can be brittle but you should know what Install Locations are being
   * defined for your own application.
   */
  const unsigned long PRIORITY_APP_PROFILE        = 0;
  const unsigned long PRIORITY_APP_SYSTEM_USER    = 10;
  const unsigned long PRIORITY_XRE_SYSTEM_USER    = 100;
  const unsigned long PRIORITY_APP_SYSTEM_GLOBAL  = 1000;
  const unsigned long PRIORITY_XRE_SYSTEM_GLOBAL  = 10000;
    
  /**
   * The priority level of this Install Location in loading. 
   */
  readonly attribute long priority;
  
  /**
   * Gets the directory that contains an item.
   * @param   id
   *          The GUID of the item.
   * @returns The location of the item. 
   */
  nsIFile getItemLocation(in AString id);

  /**
   * Retrieves the GUID for an item at the specified location.
   * @param   file
   *          The location where an item might live.
   * @returns The ID for an item that might live at the location specified.
   *
   * N.B. This function makes no promises about whether or not this path is
   *      actually maintained by this Install Location.
   */
  AString getIDForLocation(in nsIFile file);

  /**
   * Gets a nsIFile object for a file within an item's directory structure.
   * @param   id
   *          The GUID of the item.
   * @param   path
   *          The path to the file beneath an Extension's directory
   * @returns A file object at the requested location. The file does not
   *          necessarily have to exist.
   */
  nsIFile getItemFile(in AString id, in AString path);

  /**
   * Determines whether or not an item's resources are managed by the Extension
   * System or by some other user or process. For example, items linked to by
   * text links are managed by the user, and items linked to from Registry
   * Install Locations are usually managed by other applications or installers.
   *
   * @param   id
   *          The GUID of the item.
   * @returns true if the item's resources are managed independently of the
   *          Extension System, false otherwise.
   */
  boolean itemIsManagedIndependently(in AString id);
};

/**
 * Interface for handling download and install notifications for Extensions
 * and Themes.
 */
[scriptable, uuid(9048223f-ec50-49e5-9866-80ee8f26179d)]
interface nsIExtensionDownloadListener : nsISupports
{
  /**
   * Install/Download state has changed
   * @param   url
   *          The url that state changed for
   * @param   state
   *          The new state. States are defined in nsIXPIProgressDialog
   * @param   value
   *          Some data about the new state
   */
  void onStateChange(in AString url, in short state, in long value);

  /**
   * Progress occurred in the download/install operation
   * @param   url
   *          The url that progress occurred for
   * @param   value
   *          The value of the current progress
   * @param   maxValue
   *          The maximum value |value| can reach
   */
  void onProgress(in AString url, in unsigned long value, 
                  in unsigned long maxValue);
};

/**
 * Interface representing a system for the installation and management of
 * Extensions, Themes etc. 
 *
 * XXXben - Some of this stuff should go into a management-ey interface, 
 *          some into an app-startup-ey interface.
 */
[scriptable, uuid(cb90632b-4838-44c3-991c-0964e918af4b)]
interface nsIExtensionManager : nsISupports
{
  /**
   * Starts the Extension Manager, checking for item changes, additions and
   * removals, and finishing pending operations.
   * @param   commandLine
   *          The command line the application was started with.
   * @returns true if the application has rewritten the extensions.ini file
   *          and needs to restart to register components/chrome etc, 
   *          false otherwise
   */
  boolean start(in nsICommandLine commandLine);

  /** 
   * Determines if there are incompatible items installed (and offers to
   * upgrade them to newer versions if available, via a UI). 
   * @returns true if there were incompatible items that were disabled
   *          and the application needs to restart to re-register components,
   *          chrome etc, false otherwise.
   */
  boolean checkForMismatches();

  /**
   * Handle command line flags, e.g. -install-global-[extension|theme]
   * @param   cmdLine
   *          the command line the application was started with
   * XXXben - move this off this API - currently it is only used for 
   *          global installation, and the apprunner can do this directly
   *          with |installItemFromFile|
   */
  void handleCommandLineArgs(in nsICommandLine cmdline);

  /**
   * Gets the Install Location for an item
   * @param   id
   *          The GUID of the item
   * @returns The Install Location where the item is installed.
   */
  nsIInstallLocation getInstallLocation(in AString id);

  /**
   * An enumeration of all registered Install Items
   */
  readonly attribute nsISimpleEnumerator installLocations;

  /**
   * Installs an item from a XPI/JAR file into the location specified. 
   * @param   xpiFile
   *          The source file to install from. This function stages a copy
   *          of this file for persistence across potential application 
   *          restarts, you are responsible for removing the file you pass
   *          in. 
   * @param   installLocationKey
   *          The name identifier of an Install Location to install into.
   */
  void installItemFromFile(in nsIFile xpiFile, in AString installLocationKey);

  /**
   * Uninstalls an item
   * @param   id
   *          The GUID of the item.
   */
  void uninstallItem(in AString id);

  /**
   * Enables a disabled item
   * @param   id
   *          The GUID of the item.
   */
  void enableItem(in AString id);

  /**
   * Disables an enabled item
   * @param   id
   *          The GUID of the item.
   */
  void disableItem(in AString id);

  /**
   * Checks for updates to a list of items.
   * @param   items
   *          An array of nsIUpdateItems to check for updates for.
   * @param   itemCount
   *          The length of |items|
   * @param   versionUpdateOnly
   *          false if this check should find the newest versions available,
   *          true if it should only find newer target application compatibility
   *          information for the currently installed version.
   */
  void update([array, size_is(itemCount)] in nsIUpdateItem items,
               in unsigned long itemCount, 
               in unsigned long versionUpdateOnly);

  /**
   * Gets a nsIUpdateItem for the item with the specified id.
   * @param   id
   *          The GUID of the item to construct a nsIUpdateItem for.
   * @returns The nsIUpdateItem representing the item.
   */
  nsIUpdateItem getItemForID(in AString id);

  /**
   * Retrieves a list of visible nsIUpdateItems of items matching the 
   * specified type.
   * @param   type
   *          The type of item to return.
   * @param   countRef
   *          The XPCJS reference to the number of items returned.
   * @returns An array of nsIUpdateItems matching the id/type filter.
   *
   * XXXben - it would be good if this function took an optional 
   *          install location.
   */
  void getItemList(in unsigned long type, out unsigned long itemCount,
                   [retval, array, size_is(itemCount)] out nsIUpdateItem items);

  /**
   * The Extensions Datasource
   * XXXben - the datasource should be registered with the RDF system, so it 
   *          can be accessed via rdf:extensions, and not exposed through the API
   *          like this.
   */
  readonly attribute nsIRDFDataSource datasource;

  /**
   * Adds active download entries to the UI
   * @param   items
   *          A list of nsIUpdateItems to entries to add
   * @param   itemCount
   *          The length of |items|
   */
  void addDownloads([array, size_is(itemCount)] in nsIUpdateItem items,
                    in unsigned long itemCount);

  /**
   * Removes an active download from the UI
   * @param   url
   *          The URL of the active download to remove
   */
  void removeDownload(in AString url);

  /**
   * Adds a download progress listener so the front end can listen to download
   * and install progress.
   * @param   listener
   *          The listener to add
   * @returns the index of the added listen in the listener list. 
   */
  long addDownloadListener(in nsIExtensionDownloadListener listener);

  /**
   * Removes a download progress listener.
   * @param   index
   *          The index of the listener to remove.
   */
  void removeDownloadListenerAt(in long index);

  /**
   * Move an Item to the index of another item in its container.
   * @param   movingID
   *          The ID of an item to be moved.
   * @param   destinationID
   *          The ID of an item to move an item to.
   */
  void moveToIndexOf(in AString movingID, in AString destinationID);
};

/**
 * Interface representing an object that can update a set of Extensions,
 * Themes etc. 
 */
[scriptable, uuid(c0b7517f-0b3a-41a2-bde8-ba3ac8a5af47)]
interface nsIExtensionItemUpdater : nsISupports
{
  /**
   * Checks for updates to a list of items.
   * @param   items
   *          An array of nsIUpdateItems to check for updates for.
   * @param   itemCount
   *          The length of |items|
   * @param   versionUpdateOnly
   *          false if this check should find the newest versions available,
   *          true if it should only find newer target application compatibility
   *          information for the currently installed version.
   */
  void checkForUpdates([array, size_is(itemCount)] in nsIUpdateItem items,
                       in unsigned long itemCount, 
                       in boolean versionUpdateOnly);

  /**
   * The event that spawned the update check. Types defined in 
   * nsIUpdateService
   */
  readonly attribute unsigned short sourceEvent;

  /**
   * The nsIUpdateItem types being checked for updates to.
   */
  readonly attribute unsigned long updateTypes;
};

%{ C++
/**
 * Install Location Key for Application-Global Items
 */
#define NS_INSTALL_LOCATION_APPGLOBAL NS_LITERAL_STRING("app-global")

/**
 * Install Location Key for Application-Profile Items
 */
#define NS_INSTALL_LOCATION_APPPROFILE NS_LITERAL_STRING("app-profile")

/** 
 * The category that contains a list of contract-ids to Install Location 
 * services.
 */
#define CATEGORY_INSTALL_LOCATIONS "extension-install-locations"

/**
 * The observer topic to listen to for actions performed on installed
 * items.
 */
#define EM_ACTION_REQUESTED_TOPIC "em-action-requested"

#define EM_ITEM_INSTALLED   "item-installed"
#define EM_ITEM_UPGRADED    "item-upgraded"
#define EM_ITEM_UNINSTALLED "item-uninstalled"
#define EM_ITEM_ENABLED     "item-enabled"
#define EM_ITEM_DISABLED    "item-disabled"

%}

