// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

[permissions=downloads]
namespace downloads {
  [inline_doc] dictionary HeaderNameValuePair {
    // Name of the HTTP header.
    DOMString name;

    // Value of the HTTP header.
    DOMString value;
  };

  [inline_doc] enum HttpMethod {GET, POST};

  [inline_doc] dictionary DownloadOptions {
    // The URL to download.
    DOMString url;

    // A file path relative to the Downloads directory to contain the downloaded
    // file.
    DOMString? filename;

    // Use a file-chooser to allow the user to select a filename.
    boolean? saveAs;

    // The HTTP method to use if the URL uses the HTTP[S] protocol.
    HttpMethod? method;

    // Extra HTTP headers to send with the request if the URL uses the HTTP[s]
    // protocol. Each header is represented as a dictionary containing the keys
    // <code>name</code> and either <code>value</code> or
    // <code>binaryValue</code>, restricted to those allowed by XMLHttpRequest.
    HeaderNameValuePair[]? headers;

    // Post body.
    DOMString? body;
  };

  // <dl><dt>file</dt>
  //     <dd>The download's filename is suspicious.</dd>
  //     <dt>url</dt>
  //     <dd>The download's URL is known to be malicious.</dd>
  //     <dt>content</dt>
  //     <dd>The downloaded file is known to be malicious.</dd>
  //     <dt>uncommon</dt>
  //     <dd>The download's URL is not commonly downloaded and could be
  //     dangerous.</dd>
  //     <dt>safe</dt>
  //     <dd>The download presents no known danger to the user's computer.</dd>
  // </dl>
  // These string constants will never change, however the set of DangerTypes
  // may change.
  enum DangerType {file, url, content, uncommon, safe};

  // <dl><dt>in_progress</dt>
  //     <dd>The download is currently receiving data from the server.</dd>
  //     <dt>interrupted</dt>
  //     <dd>An error broke the connection with the file host.</dd>
  //     <dt>complete</dt>
  //     <dd>The download completed successfully.</dd>
  // </dl>
  // These string constants will never change, however the set of States may
  // change.
  enum State {in_progress, interrupted, complete};

  // The state of the process of downloading a file.
  dictionary DownloadItem {
    // An identifier that is persistent across browser sessions.
    long id;

    // Absolute URL.
    DOMString url;

    // Absolute local path.
    DOMString filename;

    // False if this download is recorded in the history, true if it is not
    // recorded.
    boolean incognito;

    // Indication of whether this download is thought to be safe or known to be
    // suspicious.
    DangerType danger;

    // True if the user has accepted the download's danger.
    boolean? dangerAccepted;

    // The file's MIME type.
    DOMString mime;

    // Number of milliseconds between the unix epoch and when this download
    // began.
    long startTime;

    // Number of milliseconds between the unix epoch and when this download
    // ended.
    long? endTime;

    // Indicates whether the download is progressing, interrupted, or complete.
    State state;

    // True if the download has stopped reading data from the host, but kept the
    // connection open.
    boolean paused;

    // Number indicating why a download was interrupted.
    long? error;

    // Number of bytes received so far from the host, without considering file
    // compression.
    long bytesReceived;

    // Number of bytes in the whole file, without considering file compression,
    // or -1 if unknown.
    long totalBytes;

    // Number of bytes in the whole file post-decompression, or -1 if unknown.
    long fileSize;
  };

  [inline_doc] dictionary DownloadQuery {
    // This space-separated string of search terms that may be grouped using
    // quotation marks limits results to <a
    // href='#type-DownloadItem'>DownloadItems</a> whose <code>filename</code>
    // or <code>url</code> contain all of the search terms that do not begin with a dash '-'
    // and none of the search terms that do begin with a dash.
    DOMString? query;

    // Limits results to <a href='#type-DownloadItem'>DownloadItems</a> that
    // started before the given ms since the epoch.
    long? startedBefore;

    // Limits results to <a href='#type-DownloadItem'>DownloadItems</a> that
    // started after the given ms since the epoch.
    long? startedAfter;

    // Limits results to <a href='#type-DownloadItem'>DownloadItems</a> that ended before the given ms since the
    // epoch.
    long? endedBefore;

    // Limits results to <a href='#type-DownloadItem'>DownloadItems</a> that ended after the given ms since the
    // epoch.
    long? endedAfter;

    // Limits results to <a href='#type-DownloadItem'>DownloadItems</a> whose
    // <code>totalBytes</code> is greater than the given integer.
    long? totalBytesGreater;

    // Limits results to <a href='#type-DownloadItem'>DownloadItems</a> whose
    // <code>totalBytes</code> is less than the given integer.
    long? totalBytesLess;

    // Limits results to <a href='#type-DownloadItem'>DownloadItems</a> whose
    // <code>filename</code> matches the given regular expression.
    DOMString? filenameRegex;

    // Limits results to <a href='#type-DownloadItem'>DownloadItems</a> whose
    // <code>url</code> matches the given regular expression.
    DOMString? urlRegex;

    // Setting this integer limits the number of results. Otherwise, all
    // matching <a href='#type-DownloadItem'>DownloadItems</a> will be returned.
    long? limit;

    // Setting this string to a <a href='#type-DownloadItem'>DownloadItem</a>
    // property sorts the <a href='#type-DownloadItem'>DownloadItems</a> prior
    // to applying the above filters. For example, setting
    // <code>orderBy='startTime'</code> sorts the <a
    // href='#type-DownloadItem'>DownloadItems</a> by their start time in
    // ascending order. To specify descending order, prefix <code>orderBy</code>
    // with a hyphen: '-startTime'.
    DOMString? orderBy;

    // The <code>id</code> of the <a href="#type-DownloadItem">DownloadItem</a>
    // that changed.
    long? id;

    // Absolute URL.
    DOMString? url;

    // Absolute local path.
    DOMString? filename;

    // Indication of whether this download is thought to be safe or known to be
    // suspicious.
    DangerType? danger;

    // True if the user has accepted the download's danger.
    boolean? dangerAccepted;

    // The file's MIME type.
    DOMString? mime;

    // Number of milliseconds between the unix epoch and when this download
    // began.
    long? startTime;

    // Number of milliseconds between the unix epoch and when this download
    // ended.
    long? endTime;

    // Indicates whether the download is progressing, interrupted, or complete.
    State? state;

    // True if the download has stopped reading data from the host, but kept the
    // connection open.
    boolean? paused;

    // Number indicating why a download was interrupted.
    long? error;

    // Number of bytes received so far from the host, without considering file
    // compression.
    long? bytesReceived;

    // Number of bytes in the whole file, without considering file compression,
    // or -1 if unknown.
    long? totalBytes;

    // Number of bytes in the whole file post-decompression, or -1 if unknown.
    long? fileSize;
  };

  [inline_doc] dictionary DownloadStringDiff {
    DOMString? previous;
    DOMString? current;
  };

  [inline_doc] dictionary DownloadLongDiff {
    long? previous;
    long? current;
  };

  [inline_doc] dictionary DownloadBooleanDiff {
    boolean? previous;
    boolean? current;
  };

  // Encapsulates a change in a DownloadItem.
  [inline_doc] dictionary DownloadDelta {
    // An identifier that is persistent across browser sessions.
    long id;

    // The change in <code>url</code>, if any.
    DownloadStringDiff? url;

    // The change in <code>filename</code>, if any.
    DownloadStringDiff? filename;

    // The change in <code>danger</code>, if any.
    DownloadStringDiff? danger;

    // The change in <code>dangerAccepted</code>, if any.
    DownloadBooleanDiff? dangerAccepted;

    // The change in <code>mime</code>, if any.
    DownloadStringDiff? mime;

    // The change in <code>startTime</code>, if any.
    DownloadLongDiff? startTime;

    // The change in <code>endTime</code>, if any.
    DownloadLongDiff? endTime;

    // The change in <code>state</code>, if any.
    DownloadStringDiff? state;

    // The change in <code>paused</code>, if any.
    DownloadBooleanDiff? paused;

    // The change in <code>error</code>, if any.
    DownloadLongDiff? error;

    // The change in <code>totalBytes</code>, if any.
    DownloadLongDiff? totalBytes;

    // The change in <code>fileSize</code>, if any.
    DownloadLongDiff? fileSize;
  };

  [inline_doc] dictionary GetFileIconOptions {
    // The size of the icon.  The returned icon will be square with dimensions
    // size * size pixels.  The default size for the icon is 32x32 pixels.
    [legalValues=(16,32)] long? size;
  };

  callback DownloadCallback = void(long downloadId);
  callback SearchCallback = void(DownloadItem[] results);
  callback EraseCallback = void(long[] erasedIds);
  callback NullCallback = void();
  callback GetFileIconCallback = void(optional DOMString iconURL);

  interface Functions {
    // Download a URL. If the URL uses the HTTP[S] protocol, then the request
    // will include all cookies currently set for its hostname. If both
    // <code>filename</code> and <code>saveAs</code> are specified, then the
    // Save As dialog will be displayed, pre-populated with the specified
    // <code>filename</code>. If the download started successfully,
    // <code>callback</code> will be called with the new <a href='#type-DownloadItem'>DownloadItem</a>'s
    // <code>downloadId</code>. If there was an error starting the download,
    // then <code>callback</code> will be called with
    // <code>downloadId=undefined</code> and <a
    // href='extension.html#property-lastError'>chrome.extension.lastError</a>
    // will contain a descriptive string. The error strings are not guaranteed
    // to remain backwards compatible between releases. You must not parse it.
    // |options|: What to download and how.
    // |callback|: Called with the id of the new <a href='#type-DownloadItem'>DownloadItem</a>.
    static void download(DownloadOptions options,
                         optional DownloadCallback callback);

    // Find <a href='#type-DownloadItem'>DownloadItems</a>. Set
    // <code>query</code> to the empty object to get all <a
    // href='#type-DownloadItem'>DownloadItems</a>. To get a specific <a
    // href='#type-DownloadItem'>DownloadItem</a>, set only the <code>id</code>
    // field.
    static void search(DownloadQuery query, SearchCallback callback);

    // Pause the download. If the request was successful the download is in a
    // paused state. Otherwise <a
    // href='extension.html#property-lastError'>chrome.extension.lastError</a>
    // contains an error message. The request will fail if the download is not
    // active.
    // |downloadId|: The id of the download to pause.
    // |callback|: Called when the pause request is completed. 
    static void pause(long downloadId, optional NullCallback callback);

    // Resume a paused download. If the request was successful the download is
    // in progress and unpaused. Otherwise <a
    // href='extension.html#property-lastError'>chrome.extension.lastError</a>
    // contains an error message. The request will fail if the download is not
    // active.
    // |downloadId|: The id of the download to resume.
    // |callback|: Called when the resume request is completed.
    static void resume(long downloadId, optional NullCallback callback);

    // Cancel a download. When <code>callback</code> is run, the download is
    // cancelled, completed, interrupted or doesn't exist anymore.
    // |downloadId|: The id of the download to cancel.
    // |callback|: Called when the cancel request is completed.
    static void cancel(long downloadId, optional NullCallback callback);

    // Retrieve an icon for the specified download. For new downloads, file
    // icons are available after the <a href='#event-onCreated'>onCreated</a>
    // event has been received. The image returned by this function while a
    // download is in progress may be different from the image returned after
    // the download is complete. Icon retrieval is done by querying the
    // underlying operating system or toolkit depending on the platform. The
    // icon that is returned will therefore depend on a number of factors
    // including state of the download, platform, registered file types and
    // visual theme. If a file icon cannot be determined, <a
    // href='extension.html#property-lastError'>chrome.extension.lastError</a>
    // will contain an error message.
    // |downloadId|: The identifier for the download.
    // |callback|: A URL to an image that represents the download.
    static void getFileIcon(long downloadId,
                            optional GetFileIconOptions options,
                            GetFileIconCallback callback);

    // Erase matching <a href='#type-DownloadItem'>DownloadItems</a> from
    // history
    [nodoc] static void erase(DownloadQuery query,
                              optional EraseCallback callback);

    // TODO(benjhayden) Comment.
    [nodoc] static void setDestination(long downloadId, DOMString relativePath);

    // Prompt the user to either accept or cancel a dangerous download.
    // <code>acceptDanger()</code> does not automatically accept dangerous
    // downloads.
    [nodoc] static void acceptDanger(long downloadId);

    // Show the downloaded file in its folder in a file manager.
    [nodoc] static void show(long downloadId);

    // Open the downloaded file.
    [nodoc] static void open(long downloadId);

    // Initiate dragging the file to another application.
    [nodoc] static void drag(long downloadId);
  };

  interface Events {
    // This event fires with the <a href='#type-DownloadItem'>DownloadItem</a>
    // object when a download begins.
    static void onCreated(DownloadItem downloadItem);

    // Fires with the <code>downloadId</code> when a download is erased from
    // history.
    // |downloadId|: The <code>id</code> of the <a href='#type-DownloadItem'>DownloadItem</a> that was erased.
    static void onErased(long downloadId);

    // When any of a <a href='#type-DownloadItem'>DownloadItem</a>'s properties
    // except <code>bytesReceived</code> changes, this event fires with the
    // <code>downloadId</code> and an object containing the properties that changed.
    static void onChanged(DownloadDelta downloadDelta);
  };
};
