/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "nsISupports.idl"

[scriptable, uuid(98d0e975-9cad-4ce3-ae2f-f878b8be6307)]
interface nsIFOG : nsISupports
{
  /**
   * Initialize FOG.
   *
   * Call it eventually. Metric data recorded beforehand will be buffered.
   *
   * @param aDataPathOverride - The path of a custom Glean data path to use
   *        instead of the profile dir.
   * @param aAppIdOverride - The application_id to use instead of
   *        "firefox.desktop".
   * @param aDisableInternalPings - Whether to disable internal pings (baseline, events, metrics).
   *        Default: false.
   */
  void initializeFOG([optional] in AUTF8String aDataPathOverride, [optional] in AUTF8String aAppIdOverride, [optional] in boolean aDisableInternalPings);

  /**
   * Register custom pings.
   *
   * Ensure all custom pings are registered with Glean.
   */
  void registerCustomPings();

  /**
   * Enable or Disable the logging of pings in the Glean SDK.
   * See https://firefox-source-docs.mozilla.org/toolkit/components/glean/dev/testing.html
   * for details.
   *
   * @param aEnableLogPings - true to enable logging, false to disable.
   */
  void setLogPings(in boolean aEnableLogPings);

  /**
   * Set the tag to be applied to pings assembled from now on.
   * See https://firefox-source-docs.mozilla.org/toolkit/components/glean/dev/testing.html
   * for details.
   *
   * @param aDebugTag - The string tag to apply.
   *                    If it cannot be applied (e.g it contains characters that are
   *                    forbidden in HTTP headers) the old value will remain.
   */
  void setTagPings(in ACString aDebugTag);

  /**
   * Send the named ping.
   * See https://firefox-source-docs.mozilla.org/toolkit/components/glean/dev/testing.html
   * for details.
   *
   * @param aPingName - The name of the ping to send. If no ping of that name
   *                    exists, or the ping is known but cannot be assembled
   *                    (e.g if it is empty), no ping will be sent.
   */
  void sendPing(in ACString aPingName);

  /**
   * Indicate that an experiment is running.
   * Glean will add an experiment annotation which is sent with pings.
   * This information is not persisted between runs.
   *
   * See `glean_core::Glean::set_experiment_active`.
   *
   * Logs on error, but does not throw.
   *
   * @param aExperimentId - The id/slug of the experiment.
   * @param aBranch - The name of the active branch of the experiment.
   * @param aExtra - Optional string -> string dictionary of extra information.
   */
  [implicit_jscontext]
  void setExperimentActive(in ACString aExperimentId, in ACString aBranch, [optional] in jsval aExtra);

  /**
   * Indicate that an experiment is no longer running.
   *
   * See `glean_core::Glean::set_experiment_inactive`.
   *
   * Logs on error, but does not throw.
   *
   * @param aExperimentId - The id/slug of the experiment from setExperimentActive.
   */
  void setExperimentInactive(in ACString aExperimentId);

  /**
   * **Test-only API**
   *
   * If the identified experiment was set active and hasn't been set inactive,
   * this will give you the active branch and extra information.
   *
   * @param aExperimentId - The id/slug of the experiment from setExperimentActive.
   *
   * @return an object of the form
   *         {branch: "branch-name", extra: {extra_key1: extra_value1, ...}}
   *         if there is an active experiment. Undefined, otherwise.
   */
  [implicit_jscontext]
  jsval testGetExperimentData(in ACString aExperimentId);

  /**
   * Set remote-configuration for metrics' disabled property.
   *
   * See [`glean_core::Glean::apply_server_knobs_config`]
   *
   * Logs on error, but does not throw.
   *
   * @param aJsonConfig - The stringified JSON object in the form
   *        {metric_base_identifier: boolean,}
   *        which may contain multiple metric object entries.
   */
  void applyServerKnobsConfig(in ACString aJsonConfig);

  /**
   * ** Test-only Method **
   *
   * Flush all data from all child processes.
   *
   * @returns A promise that resolves when the data's been stored.
   */
  [implicit_jscontext]
  Promise testFlushAllChildren();

  /**
   * ** Test-only Method **
   *
   * Reset FOG and the Glean SDK, clearing storage.
   */
  void testResetFOG([optional] in AUTF8String aDataPathOverride, [optional] in AUTF8String aAppIdOverride);

  /**
   * ** Test-only Method **
   *
   * Trigger test metric instrumentation on the GPU, RDD or Socket process.
   *
   * @param aProcessType - A PROCESS_TYPE_* value from the constants defined
   *                       in the nsIXULRuntime interface.
   *
   * @returns A promise that resolves when the test data has been added.
   *          The promise will be rejected if the process type is not supported
   *          or if sending the IPC to the child process fails.
   */
  [implicit_jscontext]
  Promise testTriggerMetrics(in unsigned long aProcessType);

  /**
   * ** Test-only Method **
   *
   * Register a metric.
   *
   * This function is deliberately not too friendly to use. You probably aren't
   * supposed to use it unless you're testing metric registration itself.
   *
   * @param aType - The metric's type.
   * @param aCategory - The metric's category.
   * @param aName - The metric's name.
   * @param aPings - The pings to send it in.
   * @param aLifetime - The metric's lifetime.
   * @param aDisabled - Whether the metric, though existing, isn't enabled.
   * @param aExtraArgs - Optional JSON string of extra args.
   */
  uint32_t testRegisterRuntimeMetric(in ACString aType,
                                 in ACString aCategory,
                                 in ACString aName,
                                 in Array<ACString> aPings,
                                 in ACString aLifetime,
                                 in boolean aDisabled,
                                 [optional] in ACString aExtraArgs);

  /**
   * ** Test-only Method **
   *
   * Register a ping.
   *
   * This function is deliberately not too friendly to use. You probably aren't
   * supposed to use it unless you're testing ping registration itself.
   *
   * @param aName - The ping's name.
   * @param aIncludeClientId - Whether the ping should include the client_id.
   * @param aSendIfEmpty - Whether the ping should send even if empty.
   * @param aIncludeInfoSections - Whether the ping should include
   *                               {client|ping}_info sections.
   * TODO(jer): docs
   * @param aReasonCodes - The list of valid reasons for ping submission.
   */
  uint32_t testRegisterRuntimePing(in ACString aName,
                                   in boolean aIncludeClientId,
                                   in boolean aSendIfEmpty,
                                   in boolean aPreciseTimestamps,
                                   in boolean aIncludeInfoSections,
                                   in boolean aEnabled,
                                   in Array<ACString> aSchedulesPings,
                                   in Array<ACString> aReasonCodes,
                                   in boolean aFollowsCollectionEnabled,
                                   in Array<ACString> aUploaderCapabilities);

  /**
   * Update the core attribution metrics in Glean.
   *
   * @param aSource - The product's attribution source (e.g. "google-play").
   * @param aMedium - The product's attribution medium (e.g. "organic" for a search engine).
   * @param aCampaign - The product's attribution campaign (e.g. "mozilla-org").
   * @param aTerm - The product's attribution term (e.g. "browser with developer tools for android").
   * @param aContent - The product's attribution content (e.g. "firefoxview").
   */
  void updateAttribution(in ACString aSource,
                         in ACString aMedium,
                         in ACString aCampaign,
                         in ACString aTerm,
                         in ACString aContent);

  /**
   * ** Test-only Method **
   *
   * Returns the core attribution data from Glean.
   *
   * @returns the core attribution data from Glean in the form
   *          `{source, medium, campaign, term, content}`.
   */
  [implicit_jscontext]
  jsval testGetAttribution();

  /**
   * Update the core distribution metrics in Glean.
   *
   * @param aName - The product's distribution name (e.g. "MozillaOnline").
   */
  void updateDistribution(in ACString aName);

  /**
   * ** Test-only Method **
   *
   * Returns the core distribution data from Glean.
   *
   * @returns the core distribution data from Glean in the form `{name}`.
   */
  [implicit_jscontext]
  jsval testGetDistribution();

  /**
   * Creates and registers a metric as specified,
   * making it and its APIs available on the JS Glean global.
   *
   * Main process only.
   *
   * Not necessary for most uses of FOG and Glean.
   * If you're not sure if you should call this,
   * err on the side of not calling it.
   *
   * @param aType - The metric's type (e.g., "counter", "string", etc.)
   * @param aCategory - The metric's category (namespace)
   * @param aName - The metric's name
   * @param aPings - The pings to send this metric in
   * @param aLifetime - The metric's lifetime (e.g., "ping", "application", "user")
   * @param aDisabled - Whether the metric is disabled
   * @param aExtraArgs - Optional JSON string of additional configuration
   * @throws NS_ERROR_INVALID_ARG if required arguments are missing
   * @throws NS_ERROR_FAILURE if registration fails
   */
  void registerRuntimeMetric(in ACString aType,
                            in ACString aCategory,
                            in ACString aName,
                            in Array<ACString> aPings,
                            in ACString aLifetime,
                            in boolean aDisabled,
                            [optional] in ACString aExtraArgs);

  /**
   * Creates and registers a ping as specified,
   * making it and its APIs available on the JS GleanPings global.
   *
   * Main process only.
   *
   * Not necessary for most uses of FOG and Glean.
   * If you're not sure if you should call this,
   * err on the side of not calling it.
   *
   * @param aName - The ping's name
   * @param aIncludeClientId - Whether the ping should include the client_id
   * @param aSendIfEmpty - Whether the ping should send even if empty
   * @param aPreciseTimestamps - Whether to use precise timestamps
   * @param aIncludeInfoSections - Whether to include client_info and ping_info sections
   * @param aEnabled - Whether the ping is enabled
   * @param aSchedulesPings - Array of pings that this ping schedules
   * @param aReasonCodes - Array of valid reason codes for this ping
   * @param aFollowsCollectionEnabled - Whether this ping follows the collection enabled setting
   * @param aUploaderCapabilities - Array of capabilities that the uploader must support to handle this ping
   * @throws NS_ERROR_INVALID_ARG if required arguments are missing
   * @throws NS_ERROR_FAILURE if registration fails
   */
  void registerRuntimePing(in ACString aName,
                          in boolean aIncludeClientId,
                          in boolean aSendIfEmpty,
                          in boolean aPreciseTimestamps,
                          in boolean aIncludeInfoSections,
                          in boolean aEnabled,
                          in Array<ACString> aSchedulesPings,
                          in Array<ACString> aReasonCodes,
                          in boolean aFollowsCollectionEnabled,
                          in Array<ACString> aUploaderCapabilities);
};
