// 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.

// Use the <code>chrome.downloads</code> API to programmatically initiate,
// monitor, manipulate, and search for downloads.
[permissions=downloads]
namespace downloads {
  [inline_doc] dictionary HeaderNameValuePair {
    // Name of the HTTP header.
    DOMString name;

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

  // <dl><dt>uniquify</dt>
  //     <dd>To avoid duplication, the <code>filename</code> is changed to
  //     include a counter before the filename extension.</dd>
  //     <dt>overwrite</dt>
  //     <dd>The existing file will be overwritten with the new file.</dd>
  //     <dt>prompt</dt>
  //     <dd>The user will be prompted with a file chooser dialog.</dd>
  // </dl>
  enum FilenameConflictAction {uniquify, overwrite, prompt};

  [inline_doc] dictionary FilenameSuggestion {
    // The $(ref:DownloadItem)'s new target $(ref:DownloadItem.filename), as a path
    // relative to the user's default Downloads directory, possibly containing
    // subdirectories. Absolute paths, empty paths, and paths containing
    // back-references ".." will be ignored.
    DOMString filename;

    // The action to take if <code>filename</code> already exists.
    FilenameConflictAction? conflictAction;
  };

  [inline_doc] enum HttpMethod {GET, POST};

  enum InterruptReason {
    FILE_FAILED,
    FILE_ACCESS_DENIED,
    FILE_NO_SPACE,
    FILE_NAME_TOO_LONG,
    FILE_TOO_LARGE,
    FILE_VIRUS_INFECTED,
    FILE_TRANSIENT_ERROR,
    FILE_BLOCKED,
    FILE_SECURITY_CHECK_FAILED,
    FILE_TOO_SHORT,
    NETWORK_FAILED,
    NETWORK_TIMEOUT,
    NETWORK_DISCONNECTED,
    NETWORK_SERVER_DOWN,
    NETWORK_INVALID_REQUEST,
    SERVER_FAILED,
    SERVER_NO_RANGE,
    SERVER_PRECONDITION,
    SERVER_BAD_CONTENT,
    SERVER_UNAUTHORIZED,
    SERVER_CERT_PROBLEM,
    USER_CANCELED,
    USER_SHUTDOWN,
    CRASH};

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

    // A file path relative to the Downloads directory to contain the downloaded
    // file, possibly containing subdirectories. Absolute paths, empty paths,
    // and paths containing back-references ".." will cause an error.
    // $(ref:onDeterminingFilename) allows suggesting a filename after the file's
    // MIME type and a tentative filename have been determined.
    DOMString? filename;

    // The action to take if <code>filename</code> already exists.
    FilenameConflictAction? conflictAction;

    // Use a file-chooser to allow the user to select a filename regardless of
    // whether <code>filename</code> is set or already exists.
    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>host</dt>
  //     <dd>The download came from a host known to distribute malicious
  //     binaries and is likely dangerous.</dd>
  //     <dt>unwanted</dt>
  //     <dd>The download is potentially unwanted or unsafe. E.g. it could make
  //     changes to browser or computer settings.</dd>
  //     <dt>safe</dt>
  //     <dd>The download presents no known danger to the user's computer.</dd>
  //     <dt>accepted</dt>
  //     <dd>The user has accepted the dangerous download.</dd>
  // </dl>
  enum DangerType {
    file, url, content, uncommon, host, unwanted, safe, accepted
  };

  // <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>
  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 URL.
    DOMString referrer;

    // 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;

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

    // The time when the download began in ISO 8601 format. May be passed
    // directly to the Date constructor: <code>chrome.downloads.search({},
    // function(items){items.forEach(function(item){console.log(new
    // Date(item.startTime))})})</code>
    DOMString startTime;

    // The time when the download ended in ISO 8601 format. May be passed
    // directly to the Date constructor: <code>chrome.downloads.search({},
    // function(items){items.forEach(function(item){if (item.endTime)
    // console.log(new Date(item.endTime))})})</code>
    DOMString? endTime;

    // Estimated time when the download will complete in ISO 8601 format. May be
    // passed directly to the Date constructor:
    // <code>chrome.downloads.search({},
    // function(items){items.forEach(function(item){if (item.estimatedEndTime)
    // console.log(new Date(item.estimatedEndTime))})})</code>
    DOMString? estimatedEndTime;

    // 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;

    // True if the download is in progress and paused, or else if it is
    // interrupted and can be resumed starting from where it was interrupted.
    boolean canResume;

    // Why the download was interrupted. Several kinds of HTTP errors may be
    // grouped under one of the errors beginning with <code>SERVER_</code>.
    // Errors relating to the network begin with <code>NETWORK_</code>, errors
    // relating to the process of writing the file to the file system begin with
    // <code>FILE_</code>, and interruptions initiated by the user begin with
    // <code>USER_</code>.
    InterruptReason? error;

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

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

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

    // Whether the downloaded file still exists. This information may be out of
    // date because Chrome does not automatically watch for file removal. Call
    // $(ref:search)() in order to trigger the check for file existence. When the
    // existence check completes, if the file has been deleted, then an
    // $(ref:onChanged) event will fire. Note that $(ref:search)() does not wait
    // for the existence check to finish before returning, so results from
    // $(ref:search)() may not accurately reflect the file system. Also,
    // $(ref:search)() may be called as often as necessary, but will not check for
    // file existence any more frequently than once every 10 seconds.
    boolean exists;

    // The identifier for the extension that initiated this download if this
    // download was initiated by an extension. Does not change once it is set.
    DOMString? byExtensionId;

    // The localized name of the extension that initiated this download if this
    // download was initiated by an extension. May change if the extension
    // changes its name or if the user changes their locale.
    DOMString? byExtensionName;
  };

  [inline_doc] dictionary DownloadQuery {
    // This array of search terms limits results to $(ref:DownloadItem) 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 $(ref:DownloadItem) that
    // started before the given ms since the epoch.
    DOMString? startedBefore;

    // Limits results to $(ref:DownloadItem) that
    // started after the given ms since the epoch.
    DOMString? startedAfter;

    // Limits results to $(ref:DownloadItem) that ended before the given ms since the
    // epoch.
    DOMString? endedBefore;

    // Limits results to $(ref:DownloadItem) that ended after the given ms since the
    // epoch.
    DOMString? endedAfter;

    // Limits results to $(ref:DownloadItem) whose
    // <code>totalBytes</code> is greater than the given integer.
    double? totalBytesGreater;

    // Limits results to $(ref:DownloadItem) whose
    // <code>totalBytes</code> is less than the given integer.
    double? totalBytesLess;

    // Limits results to $(ref:DownloadItem) whose
    // <code>filename</code> matches the given regular expression.
    DOMString? filenameRegex;

    // Limits results to $(ref:DownloadItem) whose
    // <code>url</code> matches the given regular expression.
    DOMString? urlRegex;

    // The maximum number of matching $(ref:DownloadItem) returned. Defaults to
    // 1000. Set to 0 in order to return all matching $(ref:DownloadItem). See
    // $(ref:search) for how to page through results.
    long? limit;

    // Set elements of this array to $(ref:DownloadItem) properties in order to
    // sort search results. For example, setting
    // <code>orderBy=['startTime']</code> sorts the $(ref:DownloadItem) by their
    // start time in ascending order. To specify descending order, prefix with a
    // hyphen: '-startTime'.
    DOMString[]? orderBy;

    // The <code>id</code> of the $(ref:DownloadItem) to query.
    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;

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

    // The time when the download began in ISO 8601 format.
    DOMString? startTime;

    // The time when the download ended in ISO 8601 format.
    DOMString? 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;

    // Why a download was interrupted.
    InterruptReason? error;

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

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

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

    // Whether the downloaded file exists;
    boolean? exists;
  };

  dictionary StringDelta {
    DOMString? previous;
    DOMString? current;
  };

  dictionary DoubleDelta {
    double? previous;
    double? current;
  };

  dictionary BooleanDelta {
    boolean? previous;
    boolean? current;
  };

  // Encapsulates a change in a DownloadItem.
  [inline_doc] dictionary DownloadDelta {
    // The <code>id</code> of the $(ref:DownloadItem)
    // that changed.
    long id;

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

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

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

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

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

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

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

    // The change in <code>canResume</code>, if any.
    BooleanDelta? canResume;

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

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

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

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

    // The change in <code>exists</code>, if any.
    BooleanDelta? exists;
  };

  [inline_doc] dictionary GetFileIconOptions {
    // The size of the returned icon. The icon will be square with dimensions
    // size * size pixels. The default and largest size for the icon is 32x32
    // pixels. The only supported sizes are 16 and 32. It is an error to specify
    // any other size.
    [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);
  callback SuggestFilenameCallback = void(
    optional FilenameSuggestion suggestion);

  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 $(ref:DownloadItem)'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 $(ref:runtime.lastError) will contain
    // a descriptive string. The error strings are not guaranteed to remain
    // backwards compatible between releases. Extensions must not parse it.
    // |options|: What to download and how.
    // |callback|: Called with the id of the new $(ref:DownloadItem).
    static void download(DownloadOptions options,
                         optional DownloadCallback callback);

    // Find $(ref:DownloadItem). Set <code>query</code> to the empty object to get
    // all $(ref:DownloadItem). To get a specific $(ref:DownloadItem), set only the
    // <code>id</code> field. To page through a large number of items, set
    // <code>orderBy: ['-startTime']</code>, set <code>limit</code> to the
    // number of items per page, and set <code>startedAfter</code> to the
    // <code>startTime</code> of the last item from the last page.
    static void search(DownloadQuery query, SearchCallback callback);

    // Pause the download. If the request was successful the download is in a
    // paused state. Otherwise $(ref:runtime.lastError) 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 $(ref:runtime.lastError) 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 $(ref:onCreated) 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, $(ref:runtime.lastError) 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);

    // Open the downloaded file now if the $(ref:DownloadItem) is complete;
    // otherwise returns an error through $(ref:runtime.lastError). Requires the
    // <code>"downloads.open"</code> permission in addition to the
    // <code>"downloads"</code> permission. An $(ref:onChanged) event will fire
    // when the item is opened for the first time.
    // |downloadId|: The identifier for the downloaded file.
    static void open(long downloadId);

    // Show the downloaded file in its folder in a file manager.
    // |downloadId|: The identifier for the downloaded file.
    static void show(long downloadId);

    // Show the default Downloads folder in a file manager.
    static void showDefaultFolder();

    // Erase matching $(ref:DownloadItem) from history without deleting the
    // downloaded file. An $(ref:onErased) event will fire for each
    // $(ref:DownloadItem) that matches <code>query</code>, then
    // <code>callback</code> will be called.
    static void erase(DownloadQuery query, optional EraseCallback callback);

    // Remove the downloaded file if it exists and the $(ref:DownloadItem) is
    // complete; otherwise return an error through $(ref:runtime.lastError).
    static void removeFile(long downloadId, optional NullCallback callback);

    // Prompt the user to accept a dangerous download. Does not automatically
    // accept dangerous downloads. If the download is accepted, then an
    // $(ref:onChanged) event will fire, otherwise nothing will happen.  When all
    // the data is fetched into a temporary file and either the download is not
    // dangerous or the danger has been accepted, then the temporary file is
    // renamed to the target filename, the |state| changes to 'complete', and
    // $(ref:onChanged) fires.
    // |downloadId|: The identifier for the $(ref:DownloadItem).
    // |callback|: Called when the danger prompt dialog closes.
    static void acceptDanger(long downloadId, optional NullCallback callback);

    // Initiate dragging the downloaded file to another application. Call in a
    // javascript <code>ondragstart</code> handler.
    static void drag(long downloadId);

    // Enable or disable the gray shelf at the bottom of every window associated
    // with the current browser profile. The shelf will be disabled as long as
    // at least one extension has disabled it. Enabling the shelf while at least
    // one other extension has disabled it will return an error through
    // $(ref:runtime.lastError). Requires the <code>"downloads.shelf"</code>
    // permission in addition to the <code>"downloads"</code> permission.
    static void setShelfEnabled(boolean enabled);
  };

  interface Events {
    // This event fires with the $(ref:DownloadItem) 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 $(ref:DownloadItem) that was
    // erased.
    static void onErased(long downloadId);

    // When any of a $(ref:DownloadItem)'s properties except
    // <code>bytesReceived</code> and <code>estimatedEndTime</code> changes,
    // this event fires with the <code>downloadId</code> and an object
    // containing the properties that changed.
    static void onChanged(DownloadDelta downloadDelta);

    // During the filename determination process, extensions will be given the
    // opportunity to override the target $(ref:DownloadItem.filename). Each
    // extension may not register more than one listener for this event. Each
    // listener must call <code>suggest</code> exactly once, either
    // synchronously or asynchronously. If the listener calls
    // <code>suggest</code> asynchronously, then it must return
    // <code>true</code>. If the listener neither calls <code>suggest</code>
    // synchronously nor returns <code>true</code>, then <code>suggest</code>
    // will be called automatically. The $(ref:DownloadItem) will not complete
    // until all listeners have called <code>suggest</code>. Listeners may call
    // <code>suggest</code> without any arguments in order to allow the download
    // to use <code>downloadItem.filename</code> for its filename, or pass a
    // <code>suggestion</code> object to <code>suggest</code> in order to
    // override the target filename. If more than one extension overrides the
    // filename, then the last extension installed whose listener passes a
    // <code>suggestion</code> object to <code>suggest</code> wins. In order to
    // avoid confusion regarding which extension will win, users should not
    // install extensions that may conflict. If the download is initiated by
    // $(ref:download) and the target filename is known before the MIME type and
    // tentative filename have been determined, pass <code>filename</code> to
    // $(ref:download) instead.
    [maxListeners=1] static void onDeterminingFilename(
        DownloadItem downloadItem, SuggestFilenameCallback suggest);
  };
};
