/*
 * 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 "nsIDOMElement.idl"
#include "nsIDOMHTMLDocument.idl"
#include "nsIDOMHTMLFormElement.idl"
#include "nsILocalFile.idl"
#include "nsIWritablePropertyBag2.idl"
#include "flockIListener.idl"


/**
 * Web Detective is designed to make detection of states or information on web
 * pages easier.  It is used to detect logged-in or logged-out states for
 * various web services, to detect media streams or person information on web
 * pages, etc.
 *
 * Additional usage documentation here:
 * http://developer.flock.com/wiki/Web_Detective
 */
[scriptable, uuid(91a3abf7-168c-4436-8f69-357a45f21a7d)]
interface flockIWebDetective : nsISupports {
  /**
   * Runs a detection rule or rules against a Document.  This is the most
   * versatile form of detection call, where regexps, xpath, cookies, etc. will
   * all work.
   *
   * There are also some variations that can be used in other situations:
   * @see detectForm
   * @see detectCookies
   * @see detectNoDOM
   *
   * @param aServiceName (in) The short name of the service, corresponding to
   *        the service name specified in the appropriate rules file.
   * @param aType (in) The "type" string of the rule(s) to use.
   * @param aDocument (in) A document object to run rules against.
   * @param aResults (in) A property bag to put any results in.
   * @return TRUE iff a rule was found of type aType and where all the
   *         conditions were met, otherwise FALSE.
   */
  boolean detect(in AString aServiceName,
                 in AString aType,
                 in nsIDOMDocument aDocument,
                 in nsIWritablePropertyBag2 aResults);

  /**
   * Works just like detect(), but use asyncDetect in situations where you need
   * to wait for asyncronous scripts or redirects in the container that effect
   * the DOM of its contentDocument.  It will repeatedly try to run detect() on
   * the container's content until either it succeeds or else exceeds aMaxTries.
   *
   * @param aDocContainer (in) An object which contains a content document to
   *        run rules against.
   * @param aFlockListener (in) will have onSuccess() called with aResults as
   *        the subject in the event that a rule matches within aMaxTries
   *        attempts.
   * @param aTimerPeriod (in) number of milliseconds between detection attempts.
   * @param aMaxTries (in) number of attemps.
   *
   * @see detect
   */
  void asyncDetect(in AString aServiceName,
                   in AString aType,
                   in nsIDOMElement aDocContainer,
                   in nsIWritablePropertyBag2 aResults,
                   in flockIListener aFlockListener,
                   in long aTimerPeriod,
                   in long aMaxTries);

  /**
   * Runs detection against a specific HTML Form element of a document.  Use
   * this to identify or pull data from forms, perhaps on submission of the
   * form.
   *
   * You can use all detection rules that work for .detect(), including XPath,
   * but there is also an additional <form> element that will let you run
   * XPath starting at the node of the form that was passed in.
   *
   * @param aForm (in) A form object to run rules against.
   *
   * @see detect
   */
  boolean detectForm(in AString aServiceName,
                     in AString aType,
                     in nsIDOMHTMLFormElement aForm,
                     in nsIWritablePropertyBag2 aResults);

  /**
   * Runs detection against browser cookies only, for when no document is
   * available.  Use this, for example, on startup if you want to detect
   * whether specific cookies are present or missing, etc.
   *
   * Any detection rules with URL or Document conditions will fail.
   *
   * @see detect
   */
  boolean detectCookies(in AString aServiceName,
                        in AString aType,
                        in nsIWritablePropertyBag2 aResults);

  /**
   * Basically does the same thing as detect(), but it operates on document
   * text instead of a document object.  Use this when the document text comes
   * from a flockHTTPRequest or XMLHttpRequest, since you don't have a document
   * object created in those cases.
   *
   * The drawback is that XPath is not available, so any XPath conditions in
   * the rule will just fail.
   *
   * @see detect
   */
  boolean detectNoDOM(in AString aServiceName,
                      in AString aType,
                      in AString aURL,
                      in AString aDocumentText,
                      in nsIWritablePropertyBag2 aResults);

  /**
   * Retrieves a set of session cookie descriptors, derived from the
   * sessioncookies specified in XML like this:
   *
   * <pre>
   * <service name="aServiceName"
   *          xmlns="http://www.flock.com/web-detective#">
   *   <sessioncookies>
   *     <cookie host="..." name="..." path="..."/>
   *     ...
   *   </sessioncookies>
   * </service>
   * </pre>
   *
   * @param aServiceName (in)
   * @return An nsISimpleEnumerator of nsICookie objects.
   *
   * @see nsICookie
   */
  nsISimpleEnumerator getSessionCookies(in AString aServiceName);

  /**
   * Retrieves the named string that may have been loaded for the specified
   * service.  The XML snippet could look something like this:
   *
   * <pre>
   * <service name="aServiceName"
   *          xmlns="http://www.flock.com/web-detective#">
   *   <strings>
   *     <string name="aStringName">
   *       <![CDATA[http://www.example.com/...]]>
   *     </string>
   *     ...
   *   </strings>
   * </pre>
   *
   * @param aServiceName (in)
   * @param aStringName (in)
   * @param aDefault (in) This is offered for convenience.  If no matching
   *        string is found then aDefault will be returned instead.
   * @return The matching string or else aDefault if no match is found.
   */
  AString getString(in AString aServiceName,
                    in AString aStringName,
                    in AString aDefault);

  /**
   * Retrieves the named string that may have been loaded for the specified
   * service, depending on the current locale of the browser.  The XML
   * snippet could look something like this:
   *
   * <pre>
   * <service name="aServiceName"
   *          xmlns="http://www.flock.com/web-detective#">
   *   <strings>
   *     <string name="aStringName" locale="default">
   *       <![CDATA[http://www.example.com/...]]>
   *     </string>
   *     <string name="aStringName" locale="de">
   *       <![CDATA[http://de.example.com/...]]>
   *     </string>
   *     ...
   *   </strings>
   * </pre>
   *
   * If the current locale is "de", the string in the locale="de" clause will
   * be returned.  Otherwise, you get the string in locale="default" clause.
   *
   * @param aServiceName (in)
   * @param aStringName (in)
   * @param aDefault (in) This is offered for convenience.  If no matching
   *        string is found then aDefault will be returned instead.
   * @return The matching string or else aDefault if no match is found.
   */
  AString getLocalizedString(in AString aServiceName,
                             in AString aStringName,
                             in AString aDefault);

  /**
   * Loads and parses a Web Detective XML file so that the rules it contains
   * available to be used by calls to detect(), etc.
   *
   * @param aDetectFile (in) handle to the XML file
   */
  void loadDetectFile(in nsILocalFile aDetectFile);

  /**
   * Loads and parses a Web Detective XML file that exists at the given chrome
   * location.
   *
   * @paran aChromeURL (in) chrome:// URL of the XML file.
   */
  void loadFromChrome(in AString aChromeURL);

  /**
   * @return nsiSimpleEnumerator of the services for which we have loaded XML
   *         files.
   *
   * @see flockIWebService
   */
  nsISimpleEnumerator listServices();

  /**
   * @param aServiceName (in)
   * @return The version string associated with the file loaded for the
   *         specified service.
   */
  AString getVersionForService(in AString aServiceName);

  /**
   * Checks for updates to the xml files and updates them if needed.
   *
   * @param forceUpdates (in) Makes the checkForUpdates check for updates
   *        regardless of when last update check was done.
   * @param aFlockListener (in) This is an optional flockIListener that will return
   *        onSuccess if ALL the updates succeed or onError if any fail.
   */
  void checkForUpdates(in boolean forceUpdates,
                       in flockIListener aFlockListener);

  /**
   * Tests whether the specified URL string properly belongs to the specified
   * domain.
   */
  boolean testDomain(in AString aURL, in AString aDomain);
};
