/* -*- 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 Application Update Service
 *
 * The Initial Developer of the Original Code is Google Inc.
 * Portions created by the Initial Developer are Copyright (C) 2005
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *  Ben Goodger <ben@mozilla.org>
 *
 * 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 nsIDOMDocument;
interface nsIDOMElement;
interface nsIDOMWindow;
interface nsIRequest;
interface nsIRequestObserver;
interface nsISimpleEnumerator;
interface nsITimerCallback;
interface nsIXMLHttpRequest;

/**
 * An interface that describes an object representing a patch file that can
 * be downloaded and applied to a version of this application so that it
 * can be updated.
 */
[scriptable, uuid(56863a67-bd69-42de-9f40-583e625b457d)]
interface nsIUpdatePatch : nsISupports
{
  /**
   * The type of this patch:
   * "partial"      A binary difference between two application versions
   * "complete"     A complete patch containing all of the replacement files
   *                to update to the new version
   */
  attribute AString type;

  /**
   * The URL this patch was being downloaded from
   */
  attribute AString URL;

  /**
   * The hash function to use when determining this file's integrity
   */
  attribute AString hashFunction;

  /**
   * The value of the hash function named above that should be computed if
   * this file is not corrupt.
   */
  attribute AString hashValue;
  
  /**
   * The size of this file, in bytes. 
   */
  attribute unsigned long size;

  /**
   * The state of this patch
   */
  attribute AString state;

  /**
   * true if this patch is currently selected as the patch to be downloaded and
   * installed for this update transaction, false if another patch from this
   * update has been selected. 
   */
  attribute boolean selected;

  /**
   * Serializes this patch object into a DOM Element
   * @param   updates
   *          The document to serialize into
   * @returns The DOM Element created by the serialization process
   */
  nsIDOMElement serialize(in nsIDOMDocument updates);
};

/**
 * An interface that describes an object representing an available update to
 * the current application - this update may have several available patches
 * from which one must be selected to download and install, for example we
 * might select a binary difference patch first and attempt to apply that, 
 * then if the application process fails fall back to downloading a complete
 * file-replace patch. This object also contains information about the update
 * that the front end and other application services can use to learn more 
 * about what is going on.
 */
[scriptable, uuid(b0fb539e-f4ab-4ea1-bd75-e6d2813e5fc1)]
interface nsIUpdate : nsISupports
{
  /**
   * The type of update:
   *   "major"  A major new version of the Application
   *   "minor"  A minor update to the Application (e.g. security update)
   */
  attribute AString type;

  /**
   * The name of the update, or "<Application Name> <Update Version>"
   */
  attribute AString name;

  /**
   * The Application version of this update. 
   */
  attribute AString version;

  /**
   * The Addon version of this update. Used by the Extension System to track 
   * compatibility of installed addons with this update. 
   */
  attribute AString extensionVersion;

  /**
   * The Build ID of this update. Used to determine a particular build, down
   * to the hour, minute and second of its creation. This allows the system
   * to differentiate between several nightly builds with the same |version|
   * for example. 
   */
  attribute AString buildID;

  /**
   * The URL to a page which offers details about the content of this 
   * update. Ideally, this page is not the release notes but some other page
   * that summarizes the differences between this update and the previous,
   * which also links to the release notes.
   */
  attribute AString detailsURL;

  /**
   * The URL to a HTML fragment that contains a license for this update. If
   * this is specified, the user is shown the license file after they choose
   * to install the update and they must agree to it before the download 
   * commences.
   */
  attribute AString licenseURL;

  /**
   * The URL to the Update Service that supplied this update.
   */
  attribute AString serviceURL;

  /**
   * Whether or not the update being downloaded is a complete replacement of
   * the user's existing installation or a patch representing the difference
   * between the new version and the previous version.
   */
  attribute boolean isCompleteUpdate;

  /**
   * Whether or not the update is a security update or not. If this is true, 
   * then we present more serious sounding user interface messages to the 
   * user. 
   */
  attribute boolean isSecurityUpdate;

  /**
   * When the update was installed.
   */
  attribute long long installDate;

  /**
   * A message associated with this update, if any.
   */
  attribute AString statusText;

  /**
   * The currently selected patch for this update.
   */
  readonly attribute nsIUpdatePatch selectedPatch;

  /**
   * The state of the selected patch:
   *   "downloading"       The update is being downloaded.
   *   "pending"           The update is ready to be applied.
   *   "applying"          The update is being applied.
   *   "succeeded"         The update was successfully applied.
   *   "download-failed"   The update failed to be downloaded.
   *   "failed"            The update failed to be applied.
   */
  attribute AString state;

  /**
   * A numeric error code that conveys additional information about the state
   * of a failed update.  If the update is not in the "failed" state, then this
   * value is zero.
   *
   * TODO: Define typical error codes (for now, see updater/errors.h)
   */
  attribute long errorCode;

  /**
   * The number of patches supplied by this update.
   */
  readonly attribute unsigned long patchCount;

  /**
   * Retrieves a patch. 
   * @param   index
   *          The index of the patch to retrieve.
   * @returns The nsIUpdatePatch at the specified index.
   */
  nsIUpdatePatch getPatchAt(in unsigned long index);

  /**
   * Serializes this update object into a DOM Element
   * @param   updates
   *          The document to serialize into
   * @returns The DOM Element created by the serialization process
   */
  nsIDOMElement serialize(in nsIDOMDocument updates);
};

/**
 * An interface describing an object that listens to the progress of an update
 * check operation. This object is notified as the check continues, finishes
 * and if it has an error. 
 */
[scriptable, uuid(8cbceb6e-8e27-46f2-8808-444c6499f836)]
interface nsIUpdateCheckListener : nsISupports
{
  /**
   * Called every time there is a progress notification loading the Update
   * Service file.
   * @param   request
   *          The nsIXMLHttpRequest handling the update check.
   * @param   position
   *          The current byte downloaded
   * @param   totalSize
   *          The total number of bytes that have to be downloaded
   */
  void onProgress(in nsIXMLHttpRequest request, 
                  in unsigned long position,
                  in unsigned long totalSize);

  /**
   * The update check was completed. 
   * @param   request
   *          The nsIXMLHttpRequest handling the update check.
   * @param   updates
   *          An array of nsIUpdate objects listing available updates.
   * @param   updateCount
   *          The size of the |updates| array.
   */
  void onCheckComplete(in nsIXMLHttpRequest request, 
                       [array, size_is(updateCount)] in nsIUpdate updates,
                       in unsigned long updateCount);

  /**
   * An error occurred while loading the remote update service file. 
   * @param   request
   *          The nsIXMLHttpRequest handling the update check.
   * @param   update
   *          A nsIUpdate object that contains details about the 
   *          error in its |statusText| property.
   */
  void onError(in nsIXMLHttpRequest request,
               in nsIUpdate update);
};

/**
 * An interface describing an object that knows how to check for updates.
 */
[scriptable, uuid(877ace25-8bc5-452a-8586-9c1cf2871994)]
interface nsIUpdateChecker : nsISupports
{
  /**
   * Checks for available updates, notifying a listener of the results.
   * @param   listener
   *          An object implementing nsIUpdateCheckListener which is notified
   *          of the results of an update check.
   * @param   force
   *          Forces the checker to check for updates, regardless of the 
   *          current value of the user's update settings. This is used by
   *          any piece of UI that offers the user the imperative option to
   *          check for updates now, regardless of their update settings.
   *          force will not work if the system administrator has locked
   *          the app.update.enabled preference.
   */
  void checkForUpdates(in nsIUpdateCheckListener listener, in boolean force);

  /**
   * Constants for the |stopChecking| function that tell the Checker how long
   * to stop checking:
   * 
   * CURRENT_CHECK:     Stops the current (active) check only
   * CURRENT_SESSION:   Stops all checking for the current session
   * ANY_CHECKS:        Stops all checking, any session from now on
   *                    (disables update checking preferences)
   */
  const unsigned short CURRENT_CHECK    = 1;
  const unsigned short CURRENT_SESSION  = 2;
  const unsigned short ANY_CHECKS       = 3;

  /**
   * Ends any pending update check.
   * @param   duration
   *          A value representing the set of checks to stop doing.
   */
  void stopChecking(in unsigned short duration);
};

/**
 * An interface describing a global application service that handles performing
 * background update checks and provides utilities for selecting and 
 * downloading update patches.
 */
[scriptable, uuid(9849c4bf-5197-4d22-baa8-e3b44a1703d2)]
interface nsIApplicationUpdateService : nsISupports
{
  /**
   * The Update Checker used for background update checking.
   */
  readonly attribute nsIUpdateChecker backgroundChecker;

  /**
   * Selects the best update to install from a list of available updates.
   * @param   updates
   *          An array of updates that are available
   * @param   updateCount
   *          The length of the |updates| array
   */
  nsIUpdate selectUpdate([array, size_is(updateCount)] in nsIUpdate updates,
                         in unsigned long updateCount);

  /**
   * Adds a listener that receives progress and state information about the 
   * update that is currently being downloaded, e.g. to update a user 
   * interface.
   * @param   listener
   *          An object implementing nsIRequestObserver and optionally
   *          nsIProgressEventSink that is to be notified of state and
   *          progress information as the update is downloaded.
   */
  void addDownloadListener(in nsIRequestObserver listener);

  /**
   * Removes a listener that is receiving progress and state information
   * about the update that is currently being downloaded. 
   * @param   listener
   *          The listener object to remove.
   */
  void removeDownloadListener(in nsIRequestObserver listener);

  /**
   * 
   */
  AString downloadUpdate(in nsIUpdate update, in boolean background);

  /**
   * Pauses the active update download process
   */
  void pauseDownload();

  /**
   * Whether or not there is an download happening at the moment.
   */
  readonly attribute boolean isDownloading;

  /**
   * Whether or not the Update Service can download and install updates.
   * This is a function of whether or not the current user has access 
   * privileges to the install directory.
   */
  readonly attribute boolean canUpdate;
};

/**
 * An interface describing a global application service that maintains a list
 * of updates previously performed as well as the current active update. 
 */
[scriptable, uuid(fede66a9-9f96-4507-a22a-775ee885577e)]
interface nsIUpdateManager : nsISupports
{
  /**
   * Gets the update at the specified index
   * @param   index
   *          The index within the updates array
   * @returns The nsIUpdate object at the specified index
   */
  nsIUpdate getUpdateAt(in long index);

  /**
   * Gets the total number of updates in the history list. 
   */
  readonly attribute long updateCount;

  /**
   * The active (current) update. The active update is not in the history list.
   */
  attribute nsIUpdate activeUpdate;

  /**
   * Saves all updates to disk. 
   */
  void saveUpdates();
};

/**
 * An interface describing an object that can show various kinds of Update 
 * notification UI to the user. 
 */
[scriptable, uuid(22b00276-ec23-4034-a764-395da539b4be)]
interface nsIUpdatePrompt : nsISupports
{
  /**
   * Shows a user interface that checks for and then displays the available
   * updates.
   */
  void checkForUpdates();

  /**
   * Show a message advising that an update is available for download and
   * install.
   * @param   update
   *          The update to be downloaded and installed
   */
  void showUpdateAvailable(in nsIUpdate update);

  /**
   * Show a message advising that an update has now been downloaded and that
   * the user should restart their software should be restarted so that the
   * update can be installed.
   * @param   update
   *          The update that was downloaded
   */
  void showUpdateDownloaded(in nsIUpdate update);

  /**
   * Shows a message detailing the update which was installed.
   * @param   update
   *          The nsIUpdate object which was just installed
   */
  void showUpdateInstalled(in nsIUpdate update);

  /**
   * Shows an error message UI telling the user about some kind of update
   * failure, e.g. failure to apply patch.
   * @param   update
   *          The nsIUpdate object which we could not install
   */
  void showUpdateError(in nsIUpdate update);

  /**
   * Shows a list of all updates installed to date.
   * @param   parent
   *          A parent window to anchor this window to. Can be null.
   */
  void showUpdateHistory(in nsIDOMWindow parent);
};

/**
 * An interface describing a global application service that allows long 
 * duration (e.g. 1-7 or more days, weeks or months) timers to be registered
 * and then fired. 
 */
[scriptable, uuid(0765c92c-6145-4253-9db4-594d8023087e)]
interface nsIUpdateTimerManager : nsISupports
{
  /**
   * Register an interval with the timer manager. The timer manager 
   * periodically checks to see if the interval has expired and if it has
   * calls the specified callback. This is persistent across application
   * restarts and can handle intervals of long durations.
   * @param   id
   *          An id that identifies the interval, used for persistence
   * @param   callback
   *          A nsITimerCallback object that is notified when the interval
   *          expires
   * @param   interval
   *          The length of time, in milliseconds, of the interval
   */
  void registerTimer(in AString id, 
                     in nsITimerCallback callback, 
                     in unsigned long interval);
};
