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

#include <map>

#include "base/component_export.h"
#include "base/functional/callback.h"
#include "base/sequence_checker.h"
#include "base/unguessable_token.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/bindings/unique_associated_receiver_set.h"
#include "mojo/public/cpp/bindings/unique_receiver_set.h"
#include "storage/browser/blob/blob_storage_constants.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
#include "third_party/blink/public/mojom/blob/blob.mojom.h"
#include "third_party/blink/public/mojom/blob/blob_url_store.mojom.h"
#include "third_party/blink/public/mojom/devtools/inspector_issue.mojom.h"

class GURL;

namespace storage {

// This class stores the mapping of blob Urls to blobs.
class COMPONENT_EXPORT(STORAGE_BROWSER) BlobUrlRegistry {
 public:
  explicit BlobUrlRegistry(base::WeakPtr<BlobUrlRegistry> fallback = nullptr);

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

  ~BlobUrlRegistry();

  enum class MappingStatus {
    kIsMapped,
    // This refers to a third-party context attempting to access a Blob URL
    // created in a first-party context.
    kNotMappedCrossPartitionSameOriginAccessFirstPartyBlobURL,
    // This refers to either a first-party or different third-party context
    // attempting to access a Blob URL created in a third-party context.
    kNotMappedCrossPartitionSameOriginAccessThirdPartyBlobURL,
    kNotMappedOther
  };

  // Binds receivers corresponding to connections from renderer frame
  // contexts and stores them in `frame_receivers_`.
  // `partitioning_blob_url_closure` runs when the storage_key check fails
  // in `BlobURLStoreImpl::ResolveAsURLLoaderFactory` and increments the use
  // counter. `top_level_blob_document_url` should be set to the frame URL if
  // this method is called for a top-level blob URL document context.
  void AddReceiver(
      const blink::StorageKey& storage_key,
      const url::Origin& renderer_origin,
      int render_process_host_id,
      mojo::PendingAssociatedReceiver<blink::mojom::BlobURLStore> receiver,
      base::RepeatingCallback<
          void(const GURL&,
               std::optional<blink::mojom::PartitioningBlobURLInfo>)>
          partitioning_blob_url_closure,
      base::RepeatingCallback<bool()> storage_access_check_callback,
      std::optional<GURL> top_level_blob_document_url,
      const char* context_type_for_debugging,
      base::RepeatingCallback<std::string()> storage_key_debug_string_callback,
      bool partitioning_disabled_by_policy = false);

  // Binds receivers corresponding to connections from renderer worker
  // contexts and threaded worklet contexts, storing them in
  // `worker_receivers_`.
  void AddReceiver(
      const blink::StorageKey& storage_key,
      const url::Origin& renderer_origin,
      int render_process_host_id,
      mojo::PendingReceiver<blink::mojom::BlobURLStore> receiver,
      const char* context_type_for_debugging,
      base::RepeatingCallback<std::string()> storage_key_debug_string_callback,
      base::RepeatingCallback<bool()> storage_access_check_callback =
          base::BindRepeating([]() -> bool { return false; }),
      bool partitioning_disabled_by_policy = false,
      BlobURLValidityCheckBehavior validity_check_behavior =
          BlobURLValidityCheckBehavior::DEFAULT);

  // Returns the receivers corresponding to renderer frame contexts for use in
  // tests.
  auto& receivers_for_testing() { return frame_receivers_; }

  // Creates a URL mapping from blob to the given URL. Returns false if
  // there already is a map for the URL. The URL mapping will be associated with
  // the `storage_key`, and most subsequent URL lookup attempts will require a
  // matching StorageKey to succeed. `origin` is the origin of the Blob URL, and
  // `render_process_host_id` is the ID of the process where the blob URL
  // registration comes from.
  bool AddUrlMapping(const GURL& url,
                     mojo::PendingRemote<blink::mojom::Blob> blob,
                     const blink::StorageKey& storage_key,
                     const url::Origin& renderer_origin,
                     int render_process_host_id);

  // Removes the given URL mapping associated with `storage_key`. Returns false
  // if the URL wasn't mapped.
  bool RemoveUrlMapping(const GURL& url, const blink::StorageKey& storage_key);

  // Returns whether the URL is mapped to a blob and whether the URL is
  // associated with `storage_key`.
  MappingStatus IsUrlMapped(const GURL& blob_url,
                            const blink::StorageKey& storage_key) const;

  // Returns the blob from the given url. Returns a null remote if the mapping
  // doesn't exist.
  mojo::PendingRemote<blink::mojom::Blob> GetBlobFromUrl(const GURL& url);

  size_t url_count() const { return url_to_data_.size(); }

  void AddTokenMapping(const base::UnguessableToken& token,
                       const GURL& url,
                       mojo::PendingRemote<blink::mojom::Blob> blob);
  void RemoveTokenMapping(const base::UnguessableToken& token);
  bool GetTokenMapping(const base::UnguessableToken& token,
                       GURL* url,
                       mojo::PendingRemote<blink::mojom::Blob>* blob);

  // Returns the origin for a Blob URL navigation to `url`, given the precursor
  // origin and target process information.
  url::Origin GetOriginForNavigation(
      const GURL& url,
      const url::Origin& precursor_origin,
      std::optional<int> target_render_process_host_id);

  // Support adding a handler to be run when AddReceiver is called. This allows
  // browser tests to intercept incoming BlobURLStore connections and swap in
  // arbitrary BlobURLs to ensure that attempting to register certain blobs
  // causes the renderer to be terminated.
  using URLStoreCreationHook =
      base::RepeatingCallback<void(BlobUrlRegistry*, mojo::ReceiverId)>;
  static void SetURLStoreCreationHookForTesting(URLStoreCreationHook* hook);

  base::WeakPtr<BlobUrlRegistry> AsWeakPtr() {
    return weak_ptr_factory_.GetWeakPtr();
  }

 private:
  SEQUENCE_CHECKER(sequence_checker_);

  // Optional fallback BlobUrlRegistry. If lookups for URLs in this registry
  // fail, they are retried in the fallback registry. This is used to allow
  // "child" storage partitions to resolve URLs created by their "parent", while
  // not allowing the reverse.
  base::WeakPtr<BlobUrlRegistry> fallback_;

  struct BlobUrlData {
    BlobUrlData();
    ~BlobUrlData();
    BlobUrlData(BlobUrlData&&);
    BlobUrlData& operator=(BlobUrlData&&);

    mojo::PendingRemote<blink::mojom::Blob> blob;
    blink::StorageKey storage_key;
    url::Origin origin;
    int render_process_host_id;
  };

  std::map<GURL, BlobUrlData> url_to_data_;
  std::map<base::UnguessableToken,
           std::pair<GURL, mojo::PendingRemote<blink::mojom::Blob>>>
      token_to_url_and_blob_;

  // When the renderer uses the BlobUrlRegistry from a frame context or from a
  // main thread worklet context, a navigation-associated interface is used to
  // preserve message ordering. The receiver corresponding to that connection is
  // an AssociatedReceiver and gets stored in `frame_receivers_`. For workers
  // and threaded worklets, the receiver is a Receiver and gets stored in
  // `worker_receivers_`.
  mojo::UniqueAssociatedReceiverSet<blink::mojom::BlobURLStore>
      frame_receivers_;
  mojo::UniqueReceiverSet<blink::mojom::BlobURLStore> worker_receivers_;

  base::WeakPtrFactory<BlobUrlRegistry> weak_ptr_factory_{this};
};

}  // namespace storage

#endif  // STORAGE_BROWSER_BLOB_BLOB_URL_REGISTRY_H_
