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

#ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_LIMITER_H_
#define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_LIMITER_H_

#include <stddef.h>

#include <map>
#include <string>
#include <vector>

#include "base/callback.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "components/content_settings/core/common/content_settings.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/resource_request_info.h"
#include "content/public/browser/web_contents_observer.h"

class HostContentSettingsMap;
class DownloadRequestInfoBarDelegateAndroid;

namespace content {
class NavigationController;
class WebContents;
}

// DownloadRequestLimiter is responsible for determining whether a download
// should be allowed or not. It is designed to keep pages from downloading
// multiple files without user interaction. DownloadRequestLimiter is invoked
// from ResourceDispatcherHost any time a download begins
// (CanDownloadOnIOThread). The request is processed on the UI thread, and the
// request is notified (back on the IO thread) as to whether the download should
// be allowed or denied.
//
// Invoking CanDownloadOnIOThread notifies the callback and may update the
// download status. The following details the various states:
// . Each NavigationController initially starts out allowing a download
//   (ALLOW_ONE_DOWNLOAD).
// . The first time CanDownloadOnIOThread is invoked the download is allowed and
//   the state changes to PROMPT_BEFORE_DOWNLOAD.
// . If the state is PROMPT_BEFORE_DOWNLOAD and the user clicks the mouse,
//   presses enter, the space bar or navigates to another page the state is
//   reset to ALLOW_ONE_DOWNLOAD.
// . If a download is attempted and the state is PROMPT_BEFORE_DOWNLOAD the user
//   is prompted as to whether the download is allowed or disallowed. The users
//   choice stays until the user navigates to a different host. For example, if
//   the user allowed the download, multiple downloads are allowed without any
//   user intervention until the user navigates to a different host.
class DownloadRequestLimiter
    : public base::RefCountedThreadSafe<DownloadRequestLimiter> {
 public:
  // Download status for a particular page. See class description for details.
  enum DownloadStatus {
    ALLOW_ONE_DOWNLOAD,
    PROMPT_BEFORE_DOWNLOAD,
    ALLOW_ALL_DOWNLOADS,
    DOWNLOADS_NOT_ALLOWED
  };

  // Max number of downloads before a "Prompt Before Download" Dialog is shown.
  static const size_t kMaxDownloadsAtOnce = 50;

  // The callback from CanDownloadOnIOThread. This is invoked on the io thread.
  // The boolean parameter indicates whether or not the download is allowed.
  typedef base::Callback<void(bool /*allow*/)> Callback;

  // TabDownloadState maintains the download state for a particular tab.
  // TabDownloadState prompts the user with an infobar as necessary.
  // TabDownloadState deletes itself (by invoking
  // DownloadRequestLimiter::Remove) as necessary.
  // TODO(gbillock): just make this class implement PermissionBubbleRequest.
  class TabDownloadState : public content::NotificationObserver,
                           public content::WebContentsObserver {
   public:
    // Creates a new TabDownloadState. |controller| is the controller the
    // TabDownloadState tracks the state of and is the host for any dialogs that
    // are displayed. |originating_controller| is used to determine the host of
    // the initial download. If |originating_controller| is null, |controller|
    // is used. |originating_controller| is typically null, but differs from
    // |controller| in the case of a constrained popup requesting the download.
    TabDownloadState(DownloadRequestLimiter* host,
                     content::WebContents* web_contents,
                     content::WebContents* originating_web_contents);
    ~TabDownloadState() override;

    // Status of the download.
    void set_download_status(DownloadRequestLimiter::DownloadStatus status) {
      status_ = status;
    }
    DownloadRequestLimiter::DownloadStatus download_status() const {
      return status_;
    }

    // Number of "ALLOWED" downloads.
    void increment_download_count() {
      download_count_++;
    }
    size_t download_count() const {
      return download_count_;
    }

    // content::WebContentsObserver overrides.
    void DidNavigateMainFrame(
        const content::LoadCommittedDetails& details,
        const content::FrameNavigateParams& params) override;
    // Invoked when a user gesture occurs (mouse click, mouse scroll, tap, or
    // key down). This may result in invoking Remove on DownloadRequestLimiter.
    void DidGetUserInteraction(const blink::WebInputEvent::Type type) override;
    void WebContentsDestroyed() override;

    // Asks the user if they really want to allow the download.
    // See description above CanDownloadOnIOThread for details on lifetime of
    // callback.
    void PromptUserForDownload(
        const DownloadRequestLimiter::Callback& callback);

    // Invoked from DownloadRequestDialogDelegate. Notifies the delegates and
    // changes the status appropriately. Virtual for testing.
    virtual void Cancel();
    virtual void CancelOnce();
    virtual void Accept();

   protected:
    // Used for testing.
    TabDownloadState();

   private:
    // Are we showing a prompt to the user?  Determined by whether
    // we have an outstanding weak pointer--weak pointers are only
    // given to the info bar delegate or permission bubble request.
    bool is_showing_prompt() const;

    // content::NotificationObserver method.
    void Observe(int type,
                 const content::NotificationSource& source,
                 const content::NotificationDetails& details) override;

    // Remember to either block or allow automatic downloads from this origin.
    void SetContentSetting(ContentSetting setting);

    // Notifies the callbacks as to whether the download is allowed or not.
    // Updates status_ appropriately.
    void NotifyCallbacks(bool allow);

    content::WebContents* web_contents_;

    DownloadRequestLimiter* host_;

    // Host of the first page the download started on. This may be empty.
    std::string initial_page_host_;

    DownloadRequestLimiter::DownloadStatus status_;

    size_t download_count_;

    // Callbacks we need to notify. This is only non-empty if we're showing a
    // dialog.
    // See description above CanDownloadOnIOThread for details on lifetime of
    // callbacks.
    std::vector<DownloadRequestLimiter::Callback> callbacks_;

    // Used to remove observers installed on NavigationController.
    content::NotificationRegistrar registrar_;

    // Weak pointer factory for generating a weak pointer to pass to the
    // infobar.  User responses to the throttling prompt will be returned
    // through this channel, and it can be revoked if the user prompt result
    // becomes moot.
    base::WeakPtrFactory<DownloadRequestLimiter::TabDownloadState> factory_;

    DISALLOW_COPY_AND_ASSIGN(TabDownloadState);
  };

  static void SetContentSettingsForTesting(HostContentSettingsMap* settings);

  DownloadRequestLimiter();

  // Returns the download status for a page. This does not change the state in
  // anyway.
  DownloadStatus GetDownloadStatus(content::WebContents* tab);

  // Check if download can proceed and notifies the callback on UI thread.
  void CanDownload(const content::ResourceRequestInfo::WebContentsGetter&
                       web_contents_getter,
                   const GURL& url,
                   const std::string& request_method,
                   const Callback& callback);

 private:
  FRIEND_TEST_ALL_PREFIXES(DownloadTest, DownloadResourceThrottleCancels);
  friend class base::RefCountedThreadSafe<DownloadRequestLimiter>;
  friend class DownloadRequestLimiterTest;
  friend class TabDownloadState;

  ~DownloadRequestLimiter();

  // Gets the download state for the specified controller. If the
  // TabDownloadState does not exist and |create| is true, one is created.
  // See TabDownloadState's constructor description for details on the two
  // controllers.
  //
  // The returned TabDownloadState is owned by the DownloadRequestLimiter and
  // deleted when no longer needed (the Remove method is invoked).
  TabDownloadState* GetDownloadState(
      content::WebContents* web_contents,
      content::WebContents* originating_web_contents,
      bool create);

  // Does the work of updating the download status on the UI thread and
  // potentially prompting the user.
  void CanDownloadImpl(content::WebContents* originating_contents,
                       const std::string& request_method,
                       const Callback& callback);

  // Invoked when decision to download has been made.
  void OnCanDownloadDecided(
      const content::ResourceRequestInfo::WebContentsGetter&
          web_contents_getter,
      const std::string& request_method,
      const Callback& orig_callback,
      bool allow);

  // Removes the specified TabDownloadState from the internal map and deletes
  // it. This has the effect of resetting the status for the tab to
  // ALLOW_ONE_DOWNLOAD.
  void Remove(TabDownloadState* state, content::WebContents* contents);

  static HostContentSettingsMap* content_settings_;
  static HostContentSettingsMap* GetContentSettings(
      content::WebContents* contents);

  // Maps from tab to download state. The download state for a tab only exists
  // if the state is other than ALLOW_ONE_DOWNLOAD. Similarly once the state
  // transitions from anything but ALLOW_ONE_DOWNLOAD back to ALLOW_ONE_DOWNLOAD
  // the TabDownloadState is removed and deleted (by way of Remove).
  typedef std::map<content::WebContents*, TabDownloadState*> StateMap;
  StateMap state_map_;

  // Weak ptr factory used when |CanDownload| asks the delegate asynchronously
  // about the download.
  base::WeakPtrFactory<DownloadRequestLimiter> factory_;

  DISALLOW_COPY_AND_ASSIGN(DownloadRequestLimiter);
};

#endif  // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_LIMITER_H_
