/*
 * BEGIN FLOCK GPL
 *
 * Copyright Flock Inc. 2005-2009
 * http://flock.com
 *
 * This file may be used under the terms of the
 * GNU General Public License Version 2 or later (the "GPL"),
 * http://www.gnu.org/licenses/gpl.html
 *
 * 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.
 *
 * END FLOCK GPL
 */

#include "flockIListener.idl"
#include "nsIDOMHTMLDocument.idl"
#include "nsIDOMHTMLFormElement.idl"
#include "nsILoginInfo.idl"
#include "nsIPropertyBag.idl"
#include "nsISimpleEnumerator.idl"
#include "nsIStringEnumerator.idl"
#include "nsIStringBundle.idl"
#include "nsISupports.idl"
#include "nsIVariant.idl"

interface flockIWebServiceAccount;


/**
 * This is the base web service interface, and should be implemented by all web
 * service components.
 */
[scriptable, uuid(12344207-7532-1234-bf00-eb362f9c7a05)]
interface flockIWebService : nsISupports {
  /** Descriptive title for the service, as recognized by end user */
  readonly attribute AString title;

  /** Internal name for the service, all lowercase, no punctuation */
  readonly attribute AString shortName;

  /** Standard favicon URL (chrome, or web) for this service */
  readonly attribute AString icon;

  /** Url to which to take the user for this service */
  readonly attribute AString url;

  /** Expose the contractId for matching with Identities */
  readonly attribute AString contractId;

  /** RDF node id for this service */
  readonly attribute AString urn;

  /**
   * A service may provide a localized resource. Use this method to gain access
   * to this resource.
   */
  nsIStringBundle getStringBundle();

  /**
   * Determines if the service should be hidden from view.  Services are not
   * disabled, this just prevents them from being promoted in the UI.
   *
   * @return true if service should be hidden.
   */
  boolean isHidden();
};


/**
 * Interface for tracking origins of passwords.  Right now we only track
 * signup vs. not.
 */
[scriptable, uuid(b2f050fd-deba-4625-a362-45d5ce817145)]
interface flockILoginInfo : nsILoginInfo {
  attribute AString formType;
};


/**
 * Represents a third-party web service which supports user accounts.  Some of
 * the methods here are for basic account maintenance (add, get, remove
 * accounts, etc.), and some are for analyzing web page documents to determine
 * which accounts may be logged in, and which are logged out, etc.
 *
 * More documentation here:
 * http://developer.flock.com/wiki/Accounts_Management
 *
 * @see flockIWebServiceManager
 */
[scriptable, uuid(f5da9456-92d3-44d6-9374-50ce4b4882b0)]
interface flockILoginWebService : flockIWebService {
  /** Comma-separated list of web domains owned by the service */
  readonly attribute AString domains;

  /** Whether Flock must know the account password for this service */
  readonly attribute boolean needPassword;

  /** URL to redirect the user when we want him to log in */
  readonly attribute AString loginURL;

  /** Localized tooltip to be shown in the Accounts&Services Sidebar */
  readonly attribute AString tooltip;

  /**
   * A service may support multiple accounts per user.  Use this method to tell
   * Flock about an existing user account with this service.
   *
   * PRECONDITIONS:
   *  - The account must already exist with the service provider.  This
   *    function does *not* actually register a new account with the service
   *    provider.
   *  - The login/password for the account must already be registered with
   *    the flockAccountUtils service and must be retrievable with a call to
   *    {flockIAccountUtils}.getPassword(<service.URN>:<accountID>).
   *
   * @param aAccountId (in) The unique identifier used by this service to refer
   *        to this account.  This is sometimes equivalent to the login string,
   *        but not always.
   * @param aIsTransient (in) Boolean indicating whether this account should be
   *        created as a "transient" account.  (Transient accounts will exist
   *        only for this browser session.)
   * @param aFlockListener (in) An optional flockIListener that can respond to
   *        success or failure of the add operation.
   * @return An account object which implements flockIWebServiceAccount.
   *
   * @see flockIAccountUtils#getPassword
   */
  flockIWebServiceAccount addAccount(in AString aAccountId,
                                     in boolean aIsTransient,
                                     in flockIListener aFlockListener);

  /**
   * Determine whether the specified document represents a successful login.
   * No distinction is made between the first login landing page and subsequent
   * pages.  In other words, this function should return TRUE as long as the
   * aDocument represents a page in a logged-in state.
   *
   * This function may assume that .ownsDocument() has already been called on
   * the document in question, and has returned TRUE.
   *
   * @return TRUE iff aDocument reveals that the use is logged in to this
   *         web service.
   * @see ownsDocument
   */
  boolean docRepresentsSuccessfulLogin(in nsIDOMHTMLDocument aDocument);

  /**
   * Retrieve the account ID represented by aDocument.  The account in question
   * may or may not be known by Flock.
   *
   * This function may assume that .docRepresentsSuccessfulLogin() has already
   * been called on the same document, and has returned TRUE.
   *
   * @param aDocument (in) an HTML document object
   * @return The account ID as a string, or else null if an account ID can not
   *         be determined.
   *
   * @see docRepresentsSuccessfulLogin
   */
  AString getAccountIDFromDocument(in nsIDOMHTMLDocument aDocument);

  /**
   * Retrieve a urn enumeration of all the known accounts for this service.
   *
   * @return nsIStringEnumerator of RDF node ids of accounts.
   */
  nsIStringEnumerator getAccountUrns();

  /**
   * Retrieve a flockIWebServiceAccount object for the account with the
   * specified RDF node id.
   *
   * @param aUrn (in) the RDF node id for the account.
   * @return An account object which implements flockIWebServiceAccount.
   */
  flockIWebServiceAccount getAccount(in AString aUrn);

  /**
   * Retrieve a urn of an account for the first matching authenticated account.
   *
   * @return The Urn of an account.
   *         Returns null if no account exist or no account is authenticated;
   *         returns the first matching account if several accounts are
   *         authenticated.
   */
  AString getAuthenticatedAccount();

  /**
   * Retrieve the login credentials from an HTML form.
   *
   * This function may assume that .ownsLoginForm() has already been called on
   * the form in question, and has returned TRUE.
   *
   * @param aForm (in) the HTML form to check
   * @return A flockILoginInfo object with the login/password/formType, or else 
   *         null if the login/password/formType can not be determined.
   *
   * @see ownsLoginForm
   */
  flockILoginInfo getCredentialsFromForm(in nsIDOMHTMLFormElement aForm);

  /**
   * @return A string derived from the current state of session cookies for the
   *         service.  This is used to determine whether the user is still
   *         logged in to the same account, in cases where we can't tell that
   *         simply by looking at the document.
   */
  AString getSessionValue();

  /**
   * Log out from all accounts (remove cookies and deauth API if needed).
   */
  void logout();

  /**
   * Indicates whether the specified document is one that the service 'owns' or
   * cares about.
   *
   * Note that if the service has provided a value for the 'domains' attribute,
   * then this function will only get called for documents whose URL falls
   * within the specified domains... so doing a domain check again in this
   * function would be redundant.
   *
   * @param aDocument (in) an HTML document to check
   * @return TRUE iff the service cares about this document/URL, else FALSE
   *
   * @see domains
   */
  boolean ownsDocument(in nsIDOMHTMLDocument aDocument);

  /**
   * Indicated whether the specified HTML form is one that the service 'owns'
   * or cares about.  This could be because it's a login, sign-up or
   * change-password form.
   *
   * @param aForm (in) an HTML form to check
   * @return TRUE iff this is a login form for this service, else FALSE
   */
  boolean ownsLoginForm(in nsIDOMHTMLFormElement aForm);

  /**
   * Use this method to have Flock forget the account details for an existing
   * user account.
   *
   * @param aUrn (in) The RDF node id for the account to be forgotten.
   *
   * @see flockIWebServiceAccount#remove
   */
  void removeAccount(in AString aUrn);

  /**
   * Gives the service an opportunity to update the status of its account(s).
   * In particular, this should detect whether account(s) are logged in or
   * logged out, and update the isAuthenticated RDF property of those accounts
   * as appropriate.
   *
   * This function may assume that .ownsDocument() has already been called for
   * the document in question, and has returned TRUE.
   *
   * @param aDocument (in) an HTML document to check
   * @param aAccount (in) the XPCOM account which has already been
   *        detected as logged in on this page.  If not provided, then no
   *        account was detected as being logged in for aDocument.
   * @param aAuthListener (in) A flockIListener, optional, which may respond to
   *        success or failure conditions.
   *
   * @see ownsDocument
   */
  void updateAccountStatusFromDocument(in nsIDOMHTMLDocument aDocument,
                                       in flockIWebServiceAccount aAccount,
                                       in flockIListener aFlockListener);
};


/**
 * This is the account interface associated with flockILoginWebService.  It is
 * the base web service account interface, and should be implemented by all web
 * service accounts.
 *
 * More documentation here:
 * http://developer.flock.com/wiki/Accounts_Management
 *
 * @see flockILoginWebService
 */
[scriptable, uuid(42755a67-dddf-43b1-a053-e4243294a035)]
interface flockIWebServiceAccount : nsISupports {

  /** RDF node id for this account */
  readonly attribute AString urn;

  /**
   * @return a handle to the flockILoginWebService associated with this account.
   */
  flockILoginWebService getService();

  /**
   * Log in to the account, using stored username and password.
   *
   * @param aFlockListener (in) A flockIListener, optional, which may respond
   *        to success or failure conditions.
   */
  void login(in flockIListener aFlockListener);

  /**
   * If the account is currently logged in, this will mark it as logged out and
   * delete any relevant cookies for that login session.
   *
   * @param aFlockListener (in) A flockIListener, optional, which may respond
   *        to success or failure conditions.
   */
  void logout(in flockIListener aFlockListener);

  /**
   * Accounts are usually initially created in a "transient" state, meaning
   * that they will only last for the duration of the current browser session.
   * This method makes the account non-transient.
   */
  void keep();

  /**
   * @return TRUE if the account is logged in; else FALSE.
   */
  boolean isAuthenticated();

  /**
   * Gets value of account parameter aParamName customParams list.
   *
   * @param aParamName (in) parameter to return.  Candidates:
   *        accountId
   *        avatar
   *        name
   *        statusMessage
   *        lastUpdateDate
   *        nextRefresh
   *        accountMessages 
   *        authToken
   * @return nsIVariant value that corresponds to aParam for this account
   */
  nsIVariant getParam(in AString aParamName);

  /**
   * Gets value of a default param of account.
   *
   * @param aParamName (in) parameter to return.  Candidates:
   *        accountId
   *        avatar
   *        name
   *        statusMessage
   *        lastUpdateDate
   *        nextRefresh
   *        accountMessages 
   *        authToken
   */
  void setParam(in AString aParamName,
                in nsIVariant aValue);

  /**
   * Gets value of account parameter aParamName customParams list.
   *
   * @param aParamName (in) parameter to return
   * @return nsIVariant value that corresponds to aParam for this account
   */
  nsIVariant getCustomParam(in AString aParamName);

  /**
   * Gets all custom account parameters.
   *
   * @return nsIPropertyBag of all custom params for this account
   */
  nsIPropertyBag getAllCustomParams();

  /**
   * Sets value of account parameter aParamName.
   *
   * @param aParamName (in) parameter to set
   * @param aValue (in) new value for parameter
   */
  void setCustomParam(in AString aParamName,
                      in nsIVariant aValue);
};
