/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* ***** 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 Mozilla Firefox.
 *
 * The Initial Developer of the Original Code is
 * the Mozilla Foundation <http://www.mozilla.org>.
 * Portions created by the Initial Developer are Copyright (C) 2011
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Taras Glek <tglek@mozilla.com>
 *   Vladan Djeric <vdjeric@mozilla.com>
 *
 * 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"
#include "nsIFile.idl"

[scriptable, uuid(c177b6b0-5ef1-44f5-bc67-6bcf7d2518e5)]
interface nsITelemetrySessionData : nsISupports
{
  /**
   * The UUID of our previous session.
   */
  readonly attribute ACString uuid;

  /**
   * An object containing a snapshot from all registered histograms that had
   * data recorded in the previous session.
   * { name1: data1, name2: data2, .... }
   * where the individual dataN are as nsITelemetry.histogramSnapshots.
   */
  [implicit_jscontext]
  readonly attribute jsval snapshots;
};

[scriptable, function, uuid(aff36c9d-7e4c-41ab-a9b6-53773bbca0cd)]
interface nsITelemetryLoadSessionDataCallback : nsISupports
{
  void handle(in nsITelemetrySessionData data);
};

[scriptable, function, uuid(40065f26-afd2-4417-93de-c1de9adb1548)]
interface nsITelemetrySaveSessionDataCallback : nsISupports
{
  void handle(in bool success);
};

[scriptable, uuid(f23a2c8d-9286-42e9-ab1b-ed287eeade6d)]
interface nsITelemetry : nsISupports
{
  /**
   * Histogram types:
   * HISTOGRAM_EXPONENTIAL - buckets increase exponentially
   * HISTOGRAM_LINEAR - buckets increase linearly
   * HISTOGRAM_BOOLEAN - For storing 0/1 values
   * HISTOGRAM_FLAG - For storing a single value; its count is always == 1.
   */
  const unsigned long HISTOGRAM_EXPONENTIAL = 0;
  const unsigned long HISTOGRAM_LINEAR = 1;
  const unsigned long HISTOGRAM_BOOLEAN = 2;
  const unsigned long HISTOGRAM_FLAG = 3;

  /*
   * An object containing a snapshot from all of the currently registered histograms.
   * { name1: {data1}, name2:{data2}...}
   * where data is consists of the following properties:
   *   min - Minimal bucket size
   *   max - Maximum bucket size
   *   histogram_type - HISTOGRAM_EXPONENTIAL, HISTOGRAM_LINEAR, or HISTOGRAM_BOOLEAN
   *   counts - array representing contents of the buckets in the histogram
   *   ranges -  an array with calculated bucket sizes
   *   sum - sum of the bucket contents
   *   static - true for histograms defined in TelemetryHistograms.h, false for ones defined with newHistogram
   */
  [implicit_jscontext]
  readonly attribute jsval histogramSnapshots;

  /*
   * An object containing information about slow SQL prepared statements.
   *
   * {
   *   mainThread: { "sqlString1": [<hit count>, <total time>], "sqlString2": [...], ... },
   *   otherThreads: { "sqlString3": [<hit count>, <total time>], "sqlString4": [...], ... }
   * }
   *
   * where:
   *   mainThread: Slow statements that executed on the main thread
   *   otherThreads: Slow statements that executed on a non-main thread
   *   sqlString - String of the offending prepared statement
   *   hit count - The number of times this statement required longer than the threshold time to execute
   *   total time - The sum of all execution times above the threshold time for this statement
   */
  [implicit_jscontext]
  readonly attribute jsval slowSQL;

  /*
   * An array of chrome hang reports. Each element is a hang report represented
   * as an object containing the hang duration, call stack PCs and information
   * about modules in memory.
   */
  [implicit_jscontext]
  readonly attribute jsval chromeHangs;

  /**
   * An object whose properties are the names of histograms defined in
   * TelemetryHistograms.h and whose corresponding values are the textual
   * comments associated with said histograms.
   */
  [implicit_jscontext]
  readonly attribute jsval registeredHistograms;

  /** 
   * Create and return a histogram.  Parameters:
   *
   * @param name Unique histogram name
   * @param min - Minimal bucket size
   * @param max - Maximum bucket size
   * @param bucket_count - number of buckets in the histogram.
   * @param type - HISTOGRAM_EXPONENTIAL, HISTOGRAM_LINEAR or HISTOGRAM_BOOLEAN
   * The returned object has the following functions:
   *   add(int) - Adds an int value to the appropriate bucket
   *   snapshot() - Returns a snapshot of the histogram with the same data fields as in histogramSnapshots()
   */
  [implicit_jscontext]
  jsval newHistogram(in ACString name, in PRUint32 min, in PRUint32 max, in PRUint32 bucket_count, in unsigned long histogram_type);

  /**
   * Create a histogram using the current state of an existing histogram.  The
   * existing histogram must be registered in TelemetryHistograms.h.
   *
   * @param name Unique histogram name
   * @param existing_name Existing histogram name
   * The returned object has the same functions as a histogram returned from newHistogram.
   */
  [implicit_jscontext]
  jsval histogramFrom(in ACString name, in ACString existing_name);

  /**
   * Same as newHistogram above, but for histograms registered in TelemetryHistograms.h.
   *
   * @param id - unique identifier from TelemetryHistograms.h
   */
  [implicit_jscontext]
  jsval getHistogramById(in ACString id);

  /**
   * Save persistent histograms to the given file.
   *
   * @param file - filename for saving
   * @param uuid - UUID of this session
   * @param callback - function to be caled when file writing is complete
   */
  void saveHistograms(in nsIFile file, in ACString uuid,
                      in nsITelemetrySaveSessionDataCallback callback,
                      in bool isSynchronous);

  /* Reconstruct an nsITelemetryDataSession object containing histogram
   * information from the given file; the file must have been produced
   * via saveHistograms.
   *
   * This method does not modify the histogram information being
   * collected in the current session.
   *
   * The reconstructed object is then passed to the given callback.
   *
   * @param file - the file to load histogram information from
   * @param callback - function to process histogram information
   */
  void loadHistograms(in nsIFile file,
                      in nsITelemetryLoadSessionDataCallback callback,
                      in bool isSynchronous);

  /**
   * Set this to false to disable gathering of telemetry statistics.
   */
  attribute boolean canRecord;

  /**
   * A flag indicating whether Telemetry can submit official results.
   */
  readonly attribute boolean canSend;

  /** Addon telemetry hooks */

  /**
   * Register a histogram for an addon.  Throws an error if the
   * histogram name has been registered previously.
   *
   * @param addon_id - Unique ID of the addon
   * @param name - Unique histogram name
   * @param min - Minimal bucket size
   * @param max - Maximum bucket size
   * @param bucket_count - number of buckets in the histogram
   * @param histogram_type - HISTOGRAM_EXPONENTIAL, HISTOGRAM_LINEAR, or
   *        HISTOGRAM_BOOLEAN
   */
  void registerAddonHistogram(in ACString addon_id, in ACString name,
                              in PRUint32 min, in PRUint32 max,
                              in PRUint32 bucket_count,
                              in unsigned long histogram_type);

  /**
   * Return a histogram previously registered via
   * registerAddonHistogram.  Throws an error if the id/name combo has
   * not been registered via registerAddonHistogram.
   *
   * @param addon_id - Unique ID of the addon
   * @param name - Registered histogram name
   *
   * The returned object has the same functions as a histogram returned
   * from newHistogram.
   */
  [implicit_jscontext]
  jsval getAddonHistogram(in ACString addon_id, in ACString name);

  /**
   * Delete all histograms associated with the given addon id.
   *
   * @param addon_id - Unique ID of the addon
   */
  void unregisterAddonHistograms(in ACString addon_id);

  /**
   * An object containing a snapshot from all of the currently
   * registered addon histograms.
   * { addon-id1 : data1, ... }
   *
   * where data is an object whose properties are the names of the
   * addon's histograms and whose corresponding values are as in
   * histogramSnapshots.
   */
  [implicit_jscontext]
  readonly attribute jsval addonHistogramSnapshots;
};
