// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_BROWSER_PRELOADING_PRERENDER_PRERENDER_HOST_REGISTRY_H_
#define CONTENT_BROWSER_PRELOADING_PRERENDER_PRERENDER_HOST_REGISTRY_H_

#include <memory>
#include <set>
#include <string>
#include <vector>

#include "base/containers/circular_deque.h"
#include "base/containers/flat_map.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "base/timer/timer.h"
#include "base/types/pass_key.h"
#include "content/browser/preloading/preloading_confidence.h"
#include "content/browser/preloading/prerender/prerender_final_status.h"
#include "content/browser/preloading/prerender/reserved_prerender_host_info.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/content_export.h"
#include "content/common/frame.mojom-forward.h"
#include "content/public/browser/preloading.h"
#include "content/public/browser/visibility.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "third_party/blink/public/mojom/speculation_rules/speculation_rules.mojom-shared.h"

class GURL;

namespace base {
class SingleThreadTaskRunner;
}

namespace net {
class HttpResponseHeaders;
}

namespace network {
class SimpleURLLoader;
}  // namespace network

namespace content {

class FrameTree;
class NavigationRequest;
class PrerenderCancellationReason;
class PrerenderHost;
class PrerenderNewTabHandle;
class RenderFrameHostImpl;
class StoredPage;
struct PrerenderAttributes;

// PrerenderHostRegistry creates and retains a prerender host, and reserves it
// for NavigationRequest to activate the prerendered page. This is created per
// WebContentsImpl and owned by it.
//
// The APIs of this class are categorized into two: APIs for triggers and APIs
// for activators.
//
// - Triggers (e.g., SpeculationHostImpl) start prerendering by
//   CreateAndStartHost() and notify the registry of destruction of the trigger
//   by CancelHosts().
// - Activators (i.e., NavigationRequest) can reserve the prerender host on
//   activation start by ReserveHostToActivate(), activate it by
//   ActivateReservedHost(), and notify the registry of completion of the
//   activation by OnActivationFinished().
class CONTENT_EXPORT PrerenderHostRegistry
    : public WebContentsObserver,
      public base::MemoryPressureListener {
 public:
  // The time to allow prerendering kept alive in the background. All the hosts
  // that this PrerenderHostRegistry holds will be terminated when the timer
  // exceeds this. The timeout value differs depending on the trigger type. The
  // value for an embedder was determined by
  // PageLoad.Clients.Prerender.NavigationToActivation.*.
  // The value for speculation rules was determined to align with the default
  // value of BFCache's eviction timer
  // (kDefaultTimeToLiveInBackForwardCacheInSeconds).
  static constexpr base::TimeDelta kTimeToLiveInBackgroundForEmbedder =
      base::Seconds(19);
  static constexpr base::TimeDelta kTimeToLiveInBackgroundForSpeculationRules =
      base::Seconds(600);
  static constexpr int kMaxRunningSpeculationRulesImmediatePrerenders = 10;
  static constexpr int kMaxRunningSpeculationRulesNonImmediatePrerenders = 2;

  using PassKey = base::PassKey<PrerenderHostRegistry>;

  // These values are persisted to logs. Entries should not be renumbered and
  // numeric values should never be reused.
  //
  // LINT.IfChange(PrerenderProcessReuseAvailability)
  enum class PrerenderProcessReuseAvailability {
    kHasMatchableHosts = 0,
    kHasSameOriginHosts = 1,
    kHasSameSiteHosts = 2,
    kNoSameOriginOrSiteHosts = 3,
    kMaxValue = kNoSameOriginOrSiteHosts,
  };
  // LINT.ThenChange(//tools/metrics/histograms/metadata/navigation/enums.xml:PrerenderProcessReuseAvailability)

  explicit PrerenderHostRegistry(WebContents&);
  ~PrerenderHostRegistry() override;

  PrerenderHostRegistry(const PrerenderHostRegistry&) = delete;
  PrerenderHostRegistry& operator=(const PrerenderHostRegistry&) = delete;
  PrerenderHostRegistry(PrerenderHostRegistry&&) = delete;
  PrerenderHostRegistry& operator=(PrerenderHostRegistry&&) = delete;

  class Observer : public base::CheckedObserver {
   public:
    // Called once per CreateAndStartHost() call. Indicates the registry
    // received a request to create a prerender but does not necessarily mean a
    // host was created. If a host was created, it is guaranteed to be in the
    // registry at the time this is called.
    virtual void OnTrigger(const GURL& url) {}

    // Called when CancelHosts() actually cancels each host.
    virtual void OnCancel(FrameTreeNodeId host_frame_tree_node_id,
                          const PrerenderCancellationReason& reason) {}

    // Called from the registry's destructor. The observer
    // should drop any reference to the registry.
    virtual void OnRegistryDestroyed() {}
  };

  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  // For triggers.
  // Creates and starts a host. Returns the root frame tree node id of the
  // prerendered page, which can be used as the id of the host.
  // `preloading_attempt` is the attempt corresponding to this prerender, the
  // default value is set to nullptr as every case of prerendering trigger is
  // not yet integrated with PreloadingAttempt.
  // TODO(crbug.com/40234240): Remove the default value as nullptr for
  // preloading_attempt once new-tab-prerender is integrated with Preloading
  // APIs.
  FrameTreeNodeId CreateAndStartHost(
      const PrerenderAttributes& attributes,
      PreloadingAttempt* preloading_attempt = nullptr);

  // Creates and starts a host in a new WebContents so that a navigation in a
  // new tab will be able to activate it. PrerenderHostRegistry associated with
  // the new WebContents manages the started host, and `this`
  // PrerenderHostRegistry manages PrerenderNewTabHandle that owns the
  // WebContents (see `prerender_new_tab_handle_by_frame_tree_node_id_`).
  FrameTreeNodeId CreateAndStartHostForNewTab(
      const PrerenderAttributes& attributes,
      const PreloadingPredictor& creating_predictor,
      const PreloadingPredictor& enacting_predictor,
      PreloadingConfidence confidence);

  // Cancels the host registered for `frame_tree_node_id`. The host is
  // immediately removed from the map of non-reserved hosts but asynchronously
  // destroyed so that prerendered pages can cancel themselves without concern
  // for self destruction.
  // Returns true if a cancelation has occurred.
  bool CancelHost(FrameTreeNodeId frame_tree_node_id,
                  PrerenderFinalStatus final_status);
  // Same as CancelHost, but can pass a detailed reason for recording if given.
  bool CancelHost(FrameTreeNodeId frame_tree_node_id,
                  const PrerenderCancellationReason& reason);

  // Cancels the existing hosts specified in the vector with the same reason.
  // Returns a subset of `frame_tree_node_ids` that were actually cancelled.
  std::set<FrameTreeNodeId> CancelHosts(
      const std::vector<FrameTreeNodeId>& frame_tree_node_ids,
      const PrerenderCancellationReason& reason);

  // Applies CancelHost for all existing PrerenderHost.
  void CancelAllHosts(PrerenderFinalStatus final_status);

  // For activators. Finds the host to activate for a navigation for the given
  // NavigationRequest. Returns the root frame tree node id of the prerendered
  // page, which can be used as the id of the host. This doesn't reserve the
  // host so it can be destroyed or activated by another navigation. This also
  // cancels all the prerender hosts except the one to be activated. See also
  // comments on ReserveHostToActivate().
  FrameTreeNodeId FindPotentialHostToActivate(
      NavigationRequest& navigation_request);

  // For activators. Reserves the host to activate for a navigation for the
  // given NavigationRequest.
  // Returns a valid ReservedPrerenderHostInfo, which has the valid root frame
  // tree node if of the prerendered page. Returns nullopt if it's not found
  // or not ready for activation yet.
  // The caller is responsible for calling OnActivationFinished() with the id to
  // release the reserved host. This also cancels all the prerender hosts except
  // the one to be activated.
  std::optional<ReservedPrerenderHostInfo> ReserveHostToActivate(
      NavigationRequest& navigation_request,
      FrameTreeNodeId expected_host_id);

  // For activators.
  // Activates the host reserved by ReserveHostToActivate() and returns the
  // StoredPage containing the page that was activated on success, or nullptr
  // on failure.
  std::unique_ptr<StoredPage> ActivateReservedHost(
      FrameTreeNodeId frame_tree_node_id,
      NavigationRequest& navigation_request);

  RenderFrameHostImpl* GetRenderFrameHostForReservedHost(
      FrameTreeNodeId frame_tree_node_id);

  // For activators.
  // Called from the destructor of NavigationRequest that reserved the host.
  // `frame_tree_node_id` should be the id returned by ReserveHostToActivate().
  void OnActivationFinished(FrameTreeNodeId frame_tree_node_id);

  // Returns the non-reserved host with the given id. Returns nullptr if the id
  // does not match any non-reserved host.
  PrerenderHost* FindNonReservedHostById(FrameTreeNodeId frame_tree_node_id);

  // Returns true if this registry reserves a host for activation.
  bool HasReservedHost() const;

  // Returns the ownership of a pre-created WebContentsImpl that contains a
  // prerendered page that corresponds to the given params for a new tab
  // navigation, if it exists.
  std::unique_ptr<WebContentsImpl> TakePreCreatedWebContentsForNewTabIfExists(
      const mojom::CreateNewWindowParams& create_new_window_params,
      const WebContents::CreateParams& web_contents_create_params);

  // Returns the FrameTrees owned by this registry's prerender hosts.
  std::vector<FrameTree*> GetPrerenderFrameTrees();

  // Returns the non-reserved host for `prerendering_url`. Returns nullptr if
  // the URL doesn't match any non-reserved host.
  PrerenderHost* FindHostByUrlForTesting(const GURL& prerendering_url);

  // Returns the prewarmed default search engine page. The prewarm page is
  // filtered by exactly matching the search prewarm URL with the initial URL of
  // the prerender host.
  PrerenderHost* FindPrewarmSearchResultHostForTesting(
      const GURL& search_prewarm_url);

  // Returns whether prerender_new_tab_handle_by_frame_tree_node_id_ has the
  // given id.
  bool HasNewTabHandleByIdForTesting(FrameTreeNodeId frame_tree_node_id);

  // Cancels all hosts.
  void CancelAllHostsForTesting();

  // Represents the group of prerender limit calculated by PreloadingTriggerType
  // and SpeculationEagerness on GetPrerenderLimitGroup.
  enum class PrerenderLimitGroup {
    kSpeculationRulesImmediate,
    kSpeculationRulesNonImmediate,
    kEmbedder,
  };

  // May be called when it is believed to be likely that the user will perform a
  // back navigation due to the trigger indicated by `predictor` (e.g. they're
  // hovering over a back button).
  void BackNavigationLikely(PreloadingPredictor predictor);

  base::WeakPtr<PrerenderHostRegistry> GetWeakPtr();

  // Only used for tests.
  base::OneShotTimer* GetEmbedderTimerForTesting() {
    return &timeout_timer_for_embedder_;
  }
  base::OneShotTimer* GetSpeculationRulesTimerForTesting() {
    return &timeout_timer_for_speculation_rules_;
  }
  void SetTaskRunnerForTesting(
      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
  bool HasOngoingHttpCacheQueryForTesting() const {
    return !!http_cache_query_loader_;
  }

  bool PrerenderCanBeStartedWhenInitiatorIsInBackground();

  // Returns true when prerendering can be triggered for embedders without
  // hitting the number limit of running prerenders.
  bool IsAllowedToStartPrerenderingForEmbedder();

  // Cancels the existing hosts for the given origin filter.
  // Currently used for browsing data removal and Clear-Site-Data header.
  void CancelHostsByOriginFilter(
      const StoragePartition::StorageKeyMatcherFunction& storage_key_filter,
      PrerenderFinalStatus final_status);

  PrerenderHostId GetPrerenderHostIdForNavigation(
      NavigationRequest* navigation_request);

 private:
  // WebContentsObserver implementation:
  void DidStartNavigation(NavigationHandle* navigation_handle) override;
  void ReadyToCommitNavigation(NavigationHandle* navigation_handle) override;
  void DidFinishNavigation(NavigationHandle* navigation_handle) override;
  void OnVisibilityChanged(Visibility visibility) override;
  void PrimaryMainFrameRenderProcessGone(
      base::TerminationStatus status) override;

  bool CancelHostInternal(FrameTreeNodeId frame_tree_node_id,
                          const PrerenderCancellationReason& reason);
  bool CancelNewTabHostInternal(FrameTreeNodeId frame_tree_node_id,
                                const PrerenderCancellationReason& reason);

  // Returns true if `navigation_request` can activate `host`.
  bool CanNavigationActivateHost(NavigationRequest& navigation_request,
                                 PrerenderHost& host);
  void DeletePendingDeletionHosts(FrameTreeNodeId prerender_host_id);
  void ScheduleToDeleteAbandonedHost(
      std::unique_ptr<PrerenderHost> prerender_host,
      const PrerenderCancellationReason& cancellation_reason);
  void SchedulePendingDeletionPrerenderNewTabHandle(
      std::unique_ptr<PrerenderNewTabHandle> handle);

  void DeleteAbandonedHosts();

  void NotifyTrigger(const GURL& url);
  void NotifyCancel(FrameTreeNodeId host_frame_tree_node_id,
                    const PrerenderCancellationReason& reason);

  // Pops one PrerenderHost from the queue and starts the prerendering if
  // there's no running prerender and `kNoFrameTreeNode` is passed as
  // `frame_tree_node_id`. If the given `frame_tree_node_id` is valid, this
  // function starts prerendering for the id. Returns starting prerender host id
  // when it succeeds, and returns an invalid FrameTreeNodeId if it's cancelled.
  FrameTreeNodeId StartPrerendering(FrameTreeNodeId frame_tree_node_id);

  // Cancels the existing hosts that were triggered by `trigger_types`.
  void CancelHostsForTriggers(std::vector<PreloadingTriggerType> trigger_types,
                              const PrerenderCancellationReason& reason);

  // Calculates PrerenderLimitGroup by PreloadingTriggerType and
  // SpeculationEagerness.
  PrerenderLimitGroup GetPrerenderLimitGroup(
      PreloadingTriggerType trigger_type,
      std::optional<blink::mojom::SpeculationEagerness> eagerness);

  // Returns the number of hosts that prerender_host_by_frame_tree_node_id_
  // holds by limit group.
  int GetHostCountByLimitGroup(PrerenderLimitGroup limit_group);

  // Returns whether a certain type of PreloadingTriggerType is allowed to be
  // added to PrerenderHostRegistry according to the limit of the given
  // PreloadingTriggerType. SpeculationEagerness is additionally considered in
  // order to apply the limits and behaviors according to
  // PrerenderLimitGroup.
  bool IsAllowedToStartPrerenderingForTrigger(
      PreloadingTriggerType trigger_type,
      std::optional<blink::mojom::SpeculationEagerness> eagerness);

  // Called when we have the HTTP cache result of the main resource of the back
  // navigation queried by `BackNavigationLikely`.
  void OnBackResourceCacheResult(
      PreloadingPredictor predictor,
      base::WeakPtr<PreloadingAttempt> attempt,
      GURL back_url,
      scoped_refptr<net::HttpResponseHeaders> headers);

  void OnMemoryPressure(
      base::MemoryPressureLevel memory_pressure_level) override;

  void RecordPotentialPrerenderProcessReuse(bool has_machable_hosts,
                                            const GURL& naivgation_url);

  // Find a prerender host that is marked as reusable and under the
  // same site as attributes.prerendering_url.
  std::unique_ptr<PrerenderHost> FindAndTakePrerenderHostToReuse(
      const PrerenderAttributes& attributes);

  scoped_refptr<base::SingleThreadTaskRunner> GetTimerTaskRunner();

  // Holds the frame_tree_node_id of running PrerenderHost. Reset to an invalid
  // value when there's no running PrerenderHost. Tracks only the host id of
  // speculation rules triggers and ignores requests from embedder because
  // embedder requests are more urgent and we'd like to handle embedder
  // prerender independently from speculation rules requests.
  FrameTreeNodeId running_prerender_host_id_;

  // Holds the ids of upcoming prerender requests. The requests from embedder
  // trigger are prioritized and pushed to the front of the queue, while the
  // requests from the speculation rules are appended to the back. This may
  // contain ids of cancelled requests. You can identify cancelled requests by
  // checking if an id is in `prerender_host_by_frame_tree_node_id_`.
  base::circular_deque<FrameTreeNodeId> pending_prerenders_;

  // Hosts that are not reserved for activation yet. This map also includes the
  // hosts still waiting for their start.
  // TODO(crbug.com/40150744): Expire prerendered contents if they are
  // not used for a while.
  base::flat_map<FrameTreeNodeId, std::unique_ptr<PrerenderHost>>
      prerender_host_by_frame_tree_node_id_;

  // Holds the host id of non-immediate prerenders by their arrival order. It is
  // used to calculate the oldest prerender on GetOldestHostPerLimitGroup.
  base::circular_deque<FrameTreeNodeId>
      non_immediate_prerender_host_id_by_arrival_order_;

  // The host that is reserved for activation.
  std::unique_ptr<PrerenderHost> reserved_prerender_host_;

  // Handles that manage WebContents for prerendering in new tabs.
  base::flat_map<FrameTreeNodeId, std::unique_ptr<PrerenderNewTabHandle>>
      prerender_new_tab_handle_by_frame_tree_node_id_;

  // Hosts that are scheduled to be deleted asynchronously.
  // Design note: PrerenderHostRegistry should explicitly manage the hosts to be
  // deleted instead of depending on the deletion helpers like DeleteSoon() to
  // asynchronously destruct them before this instance is deleted. The helpers
  // could let the hosts and their FrameTrees outlive WebContentsImpl (the owner
  // of the registry) and results in UAF.
  std::vector<std::unique_ptr<PrerenderHost>> to_be_deleted_hosts_;

  // The list of hosts which are scheduled to be deleted when
  // `DeletePendingDeletionHosts` is called. This list is for avoiding
  // the PrerenderHost being deleted prematurely before IPC calls are completed.
  base::flat_map<FrameTreeNodeId, std::unique_ptr<PrerenderHost>>
      pending_deletion_hosts_;

  // PrerenderNewTabHandle that is scheduled to be deleted asynchronously. When
  // unload related events are dispatched, PrerenderNewTabHandle deletion needs
  // to be delayed until the dispatch of the events.
  std::unique_ptr<PrerenderNewTabHandle>
      pending_deletion_new_tab_prerender_handle_;

  // Starts running the timers when prerendering gets hidden.
  base::OneShotTimer timeout_timer_for_embedder_;
  base::OneShotTimer timeout_timer_for_speculation_rules_;
  // Only used for tests. This task runner is used for precise injection in
  // tests and for timing control.
  scoped_refptr<base::SingleThreadTaskRunner> timer_task_runner_for_testing_;

  // A pending cache-only load of a URL, used to identify whether there is an
  // entry for it in the HTTP cache.
  std::unique_ptr<network::SimpleURLLoader> http_cache_query_loader_;

  base::MemoryPressureListenerRegistration
      memory_pressure_listener_registration_;

  base::ObserverList<Observer> observers_;

  base::WeakPtrFactory<PrerenderHostRegistry> weak_factory_{this};
};

}  // namespace content

#endif  // CONTENT_BROWSER_PRELOADING_PRERENDER_PRERENDER_HOST_REGISTRY_H_
