// 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 EXTENSIONS_BROWSER_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_ACTION_H_
#define EXTENSIONS_BROWSER_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_ACTION_H_

#include <list>
#include <string>
#include <vector>

#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/ref_counted.h"
#include "extensions/browser/api/declarative/declarative_rule.h"
#include "extensions/browser/api/declarative_webrequest/request_stage.h"
#include "extensions/browser/api/web_request/web_request_api_helpers.h"
#include "extensions/common/api/events.h"
#include "url/gurl.h"

namespace base {
class Time;
class Value;
}

namespace extension_web_request_api_helpers {
struct EventResponseDelta;
}

namespace extensions {
class Extension;
class InfoMap;
struct WebRequestData;
}

namespace re2 {
class RE2;
}

namespace extensions {

typedef linked_ptr<extension_web_request_api_helpers::EventResponseDelta>
    LinkedPtrEventResponseDelta;

// Base class for all WebRequestActions of the declarative Web Request API.
class WebRequestAction : public base::RefCounted<WebRequestAction> {
 public:
  // Type identifiers for concrete WebRequestActions. If you add a new type,
  // also update the unittest WebRequestActionTest.GetName, and add a
  // WebRequestActionWithThreadsTest.Permission* unittest.
  enum Type {
    ACTION_CANCEL_REQUEST,
    ACTION_REDIRECT_REQUEST,
    ACTION_REDIRECT_TO_TRANSPARENT_IMAGE,
    ACTION_REDIRECT_TO_EMPTY_DOCUMENT,
    ACTION_REDIRECT_BY_REGEX_DOCUMENT,
    ACTION_SET_REQUEST_HEADER,
    ACTION_REMOVE_REQUEST_HEADER,
    ACTION_ADD_RESPONSE_HEADER,
    ACTION_REMOVE_RESPONSE_HEADER,
    ACTION_IGNORE_RULES,
    ACTION_MODIFY_REQUEST_COOKIE,
    ACTION_MODIFY_RESPONSE_COOKIE,
    ACTION_SEND_MESSAGE_TO_EXTENSION,
  };

  // Strategies for checking host permissions.
  enum HostPermissionsStrategy {
    STRATEGY_NONE,     // Do not check host permissions.
    STRATEGY_DEFAULT,  // Check for host permissions for all URLs
                       // before creating the delta.
    STRATEGY_HOST,     // Check that host permissions match the URL
                       // of the request.
  };

  // Information necessary to decide how to apply a WebRequestAction
  // inside a matching rule.
  struct ApplyInfo {
    const InfoMap* extension_info_map;
    const WebRequestData& request_data;
    bool crosses_incognito;
    // Modified by each applied action:
    std::list<LinkedPtrEventResponseDelta>* deltas;
    std::set<std::string>* ignored_tags;
  };

  int stages() const {
    return stages_;
  }

  Type type() const {
    return type_;
  }

  // Compares the Type of two WebRequestActions, needs to be overridden for
  // parameterized types.
  virtual bool Equals(const WebRequestAction* other) const;

  // Return the JavaScript type name corresponding to type(). If there are
  // more names, they are returned separated by a colon.
  virtual std::string GetName() const = 0;

  int minimum_priority() const {
    return minimum_priority_;
  }

  HostPermissionsStrategy host_permissions_strategy() const {
    return host_permissions_strategy_;
  }

  // Returns whether the specified extension has permission to execute this
  // action on |request|. Checks the host permission if the host permissions
  // strategy is STRATEGY_DEFAULT.
  // |apply_info->extension_info_map| may only be NULL for during testing, in
  // which case host permissions are ignored. |crosses_incognito| specifies
  // whether the request comes from a different profile than |extension_id|
  // but was processed because the extension is in spanning mode.
  bool HasPermission(ApplyInfo* apply_info,
                     const std::string& extension_id) const;

  // Factory method that instantiates a concrete WebRequestAction
  // implementation according to |json_action|, the representation of the
  // WebRequestAction as received from the extension API.
  // Sets |error| and returns NULL in case of a semantic error that cannot
  // be caught by schema validation. Sets |bad_message| and returns NULL
  // in case the input is syntactically unexpected.
  static scoped_refptr<const WebRequestAction> Create(
      content::BrowserContext* browser_context,
      const Extension* extension,
      const base::Value& json_action,
      std::string* error,
      bool* bad_message);

  // Returns a description of the modification to the request caused by
  // this action.
  virtual LinkedPtrEventResponseDelta CreateDelta(
      const WebRequestData& request_data,
      const std::string& extension_id,
      const base::Time& extension_install_time) const = 0;

  // Applies this action to a request, recording the results into
  // apply_info.deltas.
  void Apply(const std::string& extension_id,
             base::Time extension_install_time,
             ApplyInfo* apply_info) const;

 protected:
  friend class base::RefCounted<WebRequestAction>;
  virtual ~WebRequestAction();
  WebRequestAction(int stages,
                   Type type,
                   int minimum_priority,
                   HostPermissionsStrategy strategy);

 private:
  // A bit vector representing a set of extensions::RequestStage during which
  // the condition can be tested.
  const int stages_;

  const Type type_;

  // The minimum priority of rules that may be evaluated after the rule
  // containing this action.
  const int minimum_priority_;

  // Defaults to STRATEGY_DEFAULT.
  const HostPermissionsStrategy host_permissions_strategy_;
};

typedef DeclarativeActionSet<WebRequestAction> WebRequestActionSet;

//
// The following are concrete actions.
//

// Action that instructs to cancel a network request.
class WebRequestCancelAction : public WebRequestAction {
 public:
  WebRequestCancelAction();

  // Implementation of WebRequestAction:
  std::string GetName() const override;
  LinkedPtrEventResponseDelta CreateDelta(
      const WebRequestData& request_data,
      const std::string& extension_id,
      const base::Time& extension_install_time) const override;

 private:
  ~WebRequestCancelAction() override;
  DISALLOW_COPY_AND_ASSIGN(WebRequestCancelAction);
};

// Action that instructs to redirect a network request.
class WebRequestRedirectAction : public WebRequestAction {
 public:
  explicit WebRequestRedirectAction(const GURL& redirect_url);

  // Implementation of WebRequestAction:
  bool Equals(const WebRequestAction* other) const override;
  std::string GetName() const override;
  LinkedPtrEventResponseDelta CreateDelta(
      const WebRequestData& request_data,
      const std::string& extension_id,
      const base::Time& extension_install_time) const override;

 private:
  ~WebRequestRedirectAction() override;

  GURL redirect_url_;  // Target to which the request shall be redirected.

  DISALLOW_COPY_AND_ASSIGN(WebRequestRedirectAction);
};

// Action that instructs to redirect a network request to a transparent image.
class WebRequestRedirectToTransparentImageAction : public WebRequestAction {
 public:
  WebRequestRedirectToTransparentImageAction();

  // Implementation of WebRequestAction:
  std::string GetName() const override;
  LinkedPtrEventResponseDelta CreateDelta(
      const WebRequestData& request_data,
      const std::string& extension_id,
      const base::Time& extension_install_time) const override;

 private:
  ~WebRequestRedirectToTransparentImageAction() override;
  DISALLOW_COPY_AND_ASSIGN(WebRequestRedirectToTransparentImageAction);
};


// Action that instructs to redirect a network request to an empty document.
class WebRequestRedirectToEmptyDocumentAction : public WebRequestAction {
 public:
  WebRequestRedirectToEmptyDocumentAction();

  // Implementation of WebRequestAction:
  std::string GetName() const override;
  LinkedPtrEventResponseDelta CreateDelta(
      const WebRequestData& request_data,
      const std::string& extension_id,
      const base::Time& extension_install_time) const override;

 private:
  ~WebRequestRedirectToEmptyDocumentAction() override;
  DISALLOW_COPY_AND_ASSIGN(WebRequestRedirectToEmptyDocumentAction);
};

// Action that instructs to redirect a network request.
class WebRequestRedirectByRegExAction : public WebRequestAction {
 public:
  // The |to_pattern| has to be passed in RE2 syntax with the exception that
  // capture groups are referenced in Perl style ($1, $2, ...).
  explicit WebRequestRedirectByRegExAction(
      std::unique_ptr<re2::RE2> from_pattern,
      const std::string& to_pattern);

  // Conversion of capture group styles between Perl style ($1, $2, ...) and
  // RE2 (\1, \2, ...).
  static std::string PerlToRe2Style(const std::string& perl);

  // Implementation of WebRequestAction:
  bool Equals(const WebRequestAction* other) const override;
  std::string GetName() const override;
  LinkedPtrEventResponseDelta CreateDelta(
      const WebRequestData& request_data,
      const std::string& extension_id,
      const base::Time& extension_install_time) const override;

 private:
  ~WebRequestRedirectByRegExAction() override;

  std::unique_ptr<re2::RE2> from_pattern_;
  std::string to_pattern_;

  DISALLOW_COPY_AND_ASSIGN(WebRequestRedirectByRegExAction);
};

// Action that instructs to set a request header.
class WebRequestSetRequestHeaderAction : public WebRequestAction {
 public:
  WebRequestSetRequestHeaderAction(const std::string& name,
                                   const std::string& value);

  // Implementation of WebRequestAction:
  bool Equals(const WebRequestAction* other) const override;
  std::string GetName() const override;
  LinkedPtrEventResponseDelta CreateDelta(
      const WebRequestData& request_data,
      const std::string& extension_id,
      const base::Time& extension_install_time) const override;

 private:
  ~WebRequestSetRequestHeaderAction() override;

  std::string name_;
  std::string value_;
  DISALLOW_COPY_AND_ASSIGN(WebRequestSetRequestHeaderAction);
};

// Action that instructs to remove a request header.
class WebRequestRemoveRequestHeaderAction : public WebRequestAction {
 public:
  explicit WebRequestRemoveRequestHeaderAction(const std::string& name);

  // Implementation of WebRequestAction:
  bool Equals(const WebRequestAction* other) const override;
  std::string GetName() const override;
  LinkedPtrEventResponseDelta CreateDelta(
      const WebRequestData& request_data,
      const std::string& extension_id,
      const base::Time& extension_install_time) const override;

 private:
  ~WebRequestRemoveRequestHeaderAction() override;

  std::string name_;
  DISALLOW_COPY_AND_ASSIGN(WebRequestRemoveRequestHeaderAction);
};

// Action that instructs to add a response header.
class WebRequestAddResponseHeaderAction : public WebRequestAction {
 public:
  WebRequestAddResponseHeaderAction(const std::string& name,
                                    const std::string& value);

  // Implementation of WebRequestAction:
  bool Equals(const WebRequestAction* other) const override;
  std::string GetName() const override;
  LinkedPtrEventResponseDelta CreateDelta(
      const WebRequestData& request_data,
      const std::string& extension_id,
      const base::Time& extension_install_time) const override;

 private:
  ~WebRequestAddResponseHeaderAction() override;

  std::string name_;
  std::string value_;
  DISALLOW_COPY_AND_ASSIGN(WebRequestAddResponseHeaderAction);
};

// Action that instructs to remove a response header.
class WebRequestRemoveResponseHeaderAction : public WebRequestAction {
 public:
  explicit WebRequestRemoveResponseHeaderAction(const std::string& name,
                                                const std::string& value,
                                                bool has_value);

  // Implementation of WebRequestAction:
  bool Equals(const WebRequestAction* other) const override;
  std::string GetName() const override;
  LinkedPtrEventResponseDelta CreateDelta(
      const WebRequestData& request_data,
      const std::string& extension_id,
      const base::Time& extension_install_time) const override;

 private:
  ~WebRequestRemoveResponseHeaderAction() override;

  std::string name_;
  std::string value_;
  bool has_value_;
  DISALLOW_COPY_AND_ASSIGN(WebRequestRemoveResponseHeaderAction);
};

// Action that instructs to ignore rules below a certain priority.
class WebRequestIgnoreRulesAction : public WebRequestAction {
 public:
  explicit WebRequestIgnoreRulesAction(int minimum_priority,
                                       const std::string& ignore_tag);

  // Implementation of WebRequestAction:
  bool Equals(const WebRequestAction* other) const override;
  std::string GetName() const override;
  LinkedPtrEventResponseDelta CreateDelta(
      const WebRequestData& request_data,
      const std::string& extension_id,
      const base::Time& extension_install_time) const override;
  const std::string& ignore_tag() const { return ignore_tag_; }

 private:
  ~WebRequestIgnoreRulesAction() override;

  // Rules are ignored if they have a tag matching |ignore_tag_| and
  // |ignore_tag_| is non-empty.
  std::string ignore_tag_;
  DISALLOW_COPY_AND_ASSIGN(WebRequestIgnoreRulesAction);
};

// Action that instructs to modify (add, edit, remove) a request cookie.
class WebRequestRequestCookieAction : public WebRequestAction {
 public:
  typedef extension_web_request_api_helpers::RequestCookieModification
      RequestCookieModification;

  explicit WebRequestRequestCookieAction(
      linked_ptr<RequestCookieModification> request_cookie_modification);

  // Implementation of WebRequestAction:
  bool Equals(const WebRequestAction* other) const override;
  std::string GetName() const override;
  LinkedPtrEventResponseDelta CreateDelta(
      const WebRequestData& request_data,
      const std::string& extension_id,
      const base::Time& extension_install_time) const override;

 private:
  ~WebRequestRequestCookieAction() override;

  linked_ptr<RequestCookieModification> request_cookie_modification_;
  DISALLOW_COPY_AND_ASSIGN(WebRequestRequestCookieAction);
};

// Action that instructs to modify (add, edit, remove) a response cookie.
class WebRequestResponseCookieAction : public WebRequestAction {
 public:
  typedef extension_web_request_api_helpers::ResponseCookieModification
      ResponseCookieModification;

  explicit WebRequestResponseCookieAction(
      linked_ptr<ResponseCookieModification> response_cookie_modification);

  // Implementation of WebRequestAction:
  bool Equals(const WebRequestAction* other) const override;
  std::string GetName() const override;
  LinkedPtrEventResponseDelta CreateDelta(
      const WebRequestData& request_data,
      const std::string& extension_id,
      const base::Time& extension_install_time) const override;

 private:
  ~WebRequestResponseCookieAction() override;

  linked_ptr<ResponseCookieModification> response_cookie_modification_;
  DISALLOW_COPY_AND_ASSIGN(WebRequestResponseCookieAction);
};

// Action that triggers the chrome.declarativeWebRequest.onMessage event in
// the background/event/... pages of the extension.
class WebRequestSendMessageToExtensionAction : public WebRequestAction {
 public:
  explicit WebRequestSendMessageToExtensionAction(const std::string& message);

  // Implementation of WebRequestAction:
  bool Equals(const WebRequestAction* other) const override;
  std::string GetName() const override;
  LinkedPtrEventResponseDelta CreateDelta(
      const WebRequestData& request_data,
      const std::string& extension_id,
      const base::Time& extension_install_time) const override;

 private:
  ~WebRequestSendMessageToExtensionAction() override;

  std::string message_;
  DISALLOW_COPY_AND_ASSIGN(WebRequestSendMessageToExtensionAction);
};

}  // namespace extensions

#endif  // EXTENSIONS_BROWSER_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_ACTION_H_
