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

#include "storage/browser/blob/blob_url_registry.h"

#include "base/check.h"
#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/functional/callback.h"
#include "net/base/features.h"
#include "storage/browser/blob/blob_url_store_impl.h"
#include "storage/browser/blob/blob_url_utils.h"
#include "third_party/blink/public/mojom/devtools/inspector_issue.mojom.h"
#include "url/gurl.h"

namespace storage {

namespace {

BlobUrlRegistry::URLStoreCreationHook* g_url_store_creation_hook = nullptr;

}

BlobUrlRegistry::BlobUrlData::BlobUrlData() = default;
BlobUrlRegistry::BlobUrlData::~BlobUrlData() = default;
BlobUrlRegistry::BlobUrlData::BlobUrlData(BlobUrlData&&) = default;
BlobUrlRegistry::BlobUrlData& BlobUrlRegistry::BlobUrlData::operator=(
    BlobUrlData&&) = default;

BlobUrlRegistry::BlobUrlRegistry(base::WeakPtr<BlobUrlRegistry> fallback)
    : fallback_(std::move(fallback)) {}

BlobUrlRegistry::~BlobUrlRegistry() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}

void BlobUrlRegistry::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_navigation_document_url,
    const char* context_type_for_debugging,
    base::RepeatingCallback<std::string()> storage_key_debug_string_callback,
    bool partitioning_disabled_by_policy) {
  mojo::ReceiverId receiver_id = frame_receivers_.Add(
      std::make_unique<storage::BlobURLStoreImpl>(
          storage_key, renderer_origin, render_process_host_id, AsWeakPtr(),
          storage::BlobURLValidityCheckBehavior::DEFAULT,
          std::move(partitioning_blob_url_closure),
          std::move(storage_access_check_callback),
          std::move(top_level_blob_navigation_document_url),
          partitioning_disabled_by_policy, context_type_for_debugging,
          std::move(storage_key_debug_string_callback)),
      std::move(receiver));

  if (g_url_store_creation_hook) {
    g_url_store_creation_hook->Run(this, receiver_id);
  }
}

void BlobUrlRegistry::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,
    bool partitioning_disabled_by_policy,
    BlobURLValidityCheckBehavior validity_check_behavior) {
  worker_receivers_.Add(
      std::make_unique<storage::BlobURLStoreImpl>(
          storage_key, renderer_origin, render_process_host_id, AsWeakPtr(),
          validity_check_behavior, base::DoNothing(),
          std::move(storage_access_check_callback),
          // We shouldn't pass a value here because this method is not used for
          // top-level document contexts (only for workers and threaded
          // worklets).
          /*top_level_blob_navigation_document_url=*/std::nullopt,
          partitioning_disabled_by_policy, context_type_for_debugging,
          std::move(storage_key_debug_string_callback)),
      std::move(receiver));
}

bool BlobUrlRegistry::AddUrlMapping(
    const GURL& blob_url,
    mojo::PendingRemote<blink::mojom::Blob> blob,
    const blink::StorageKey& storage_key,
    const url::Origin& renderer_origin,
    int render_process_host_id) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(!BlobUrlUtils::UrlHasFragment(blob_url));
  if (IsUrlMapped(blob_url, storage_key) ==
      BlobUrlRegistry::MappingStatus::kIsMapped) {
    return false;
  }
  BlobUrlData data;
  data.blob = std::move(blob);
  data.storage_key = storage_key;
  data.origin = renderer_origin;
  data.render_process_host_id = render_process_host_id;
  url_to_data_[blob_url] = std::move(data);
  return true;
}

bool BlobUrlRegistry::RemoveUrlMapping(const GURL& blob_url,
                                       const blink::StorageKey& storage_key) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(!BlobUrlUtils::UrlHasFragment(blob_url));
  auto data_it = url_to_data_.find(blob_url);
  if (data_it == url_to_data_.end()) {
    return false;
  }
  if (data_it->second.storage_key != storage_key) {
    return false;
  }
  url_to_data_.erase(data_it);
  return true;
}

url::Origin BlobUrlRegistry::GetOriginForNavigation(
    const GURL& url,
    const url::Origin& precursor_origin,
    std::optional<int> target_render_process_host_id) {
  // Some Blob URLs have the origin embedded directly within the URL, which we
  // can get from calling url::Origin::Create() (which will extract the embedded
  // origin if it exists). Cases whether the origin is not embedded within the
  // URL (when the content part is "null") would result in an opaque origin.
  url::Origin url_origin = url::Origin::Create(url);
  if (!url_origin.opaque()) {
    return url_origin;
  }

  // The origin is not embedded within the Blob URL. Strip out the ref from the
  // URL (if it exists), and get the origin from our mapping. If
  // `target_render_process_host_id` is set, only return the origin if it was
  // registered by a process with the same ID. This keeps the legacy behavior
  // where the blob URL's origin mapping lives on the renderer process, so only
  // the renderer where the blob URL is created knows its origin, so navigations
  // to other processes can't use the mapped origin.
  GURL url_without_ref = url.GetWithoutRef();
  auto it = url_to_data_.find(url_without_ref);
  if (it != url_to_data_.end() && (!target_render_process_host_id.has_value() ||
                                   it->second.render_process_host_id ==
                                       target_render_process_host_id.value())) {
    return it->second.origin;
  }

  return url::Origin::Resolve(url, precursor_origin);
}

BlobUrlRegistry::MappingStatus BlobUrlRegistry::IsUrlMapped(
    const GURL& blob_url,
    const blink::StorageKey& storage_key) const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  auto it = url_to_data_.find(blob_url);
  if (it != url_to_data_.end()) {
    const blink::StorageKey& blob_url_key = it->second.storage_key;
    if (blob_url_key == storage_key) {
      return BlobUrlRegistry::MappingStatus::kIsMapped;
    }
    if (blob_url_key.origin() == storage_key.origin()) {
      if (blob_url_key.IsFirstPartyContext()) {
        return BlobUrlRegistry::MappingStatus::
            kNotMappedCrossPartitionSameOriginAccessFirstPartyBlobURL;
      }
      return BlobUrlRegistry::MappingStatus::
          kNotMappedCrossPartitionSameOriginAccessThirdPartyBlobURL;
    }
    // A fallback_ check isn't needed because a given Blob URL will either be
    // registered in this BlobUrlRegistry or registered in the fallback
    // BlobUrlRegistry but not both.
    return BlobUrlRegistry::MappingStatus::kNotMappedOther;
  }
  if (fallback_) {
    return fallback_->IsUrlMapped(blob_url, storage_key);
  }
  return BlobUrlRegistry::MappingStatus::kNotMappedOther;
}

mojo::PendingRemote<blink::mojom::Blob> BlobUrlRegistry::GetBlobFromUrl(
    const GURL& url) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  auto it = url_to_data_.find(BlobUrlUtils::ClearUrlFragment(url));
  if (it == url_to_data_.end()) {
    return fallback_ ? fallback_->GetBlobFromUrl(url) : mojo::NullRemote();
  }
  mojo::Remote<blink::mojom::Blob> blob(std::move(it->second.blob));
  mojo::PendingRemote<blink::mojom::Blob> result;
  blob->Clone(result.InitWithNewPipeAndPassReceiver());
  it->second.blob = blob.Unbind();
  return result;
}

void BlobUrlRegistry::AddTokenMapping(
    const base::UnguessableToken& token,
    const GURL& url,
    mojo::PendingRemote<blink::mojom::Blob> blob) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(!base::Contains(token_to_url_and_blob_, token));
  token_to_url_and_blob_.emplace(token, std::make_pair(url, std::move(blob)));
}

void BlobUrlRegistry::RemoveTokenMapping(const base::UnguessableToken& token) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(base::Contains(token_to_url_and_blob_, token));
  token_to_url_and_blob_.erase(token);
}

bool BlobUrlRegistry::GetTokenMapping(
    const base::UnguessableToken& token,
    GURL* url,
    mojo::PendingRemote<blink::mojom::Blob>* blob) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  auto it = token_to_url_and_blob_.find(token);
  if (it == token_to_url_and_blob_.end())
    return false;
  *url = it->second.first;
  mojo::Remote<blink::mojom::Blob> source_blob(std::move(it->second.second));
  source_blob->Clone(blob->InitWithNewPipeAndPassReceiver());
  it->second.second = source_blob.Unbind();
  return true;
}

// static
void BlobUrlRegistry::SetURLStoreCreationHookForTesting(
    URLStoreCreationHook* hook) {
  g_url_store_creation_hook = hook;
}

}  // namespace storage
