// Copyright 2018 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_LOADER_PREFETCH_URL_LOADER_H_
#define CONTENT_BROWSER_LOADER_PREFETCH_URL_LOADER_H_

#include <memory>
#include <optional>
#include <string>

#include "base/functional/callback.h"
#include "base/unguessable_token.h"
#include "content/browser/web_package/prefetched_signed_exchange_cache.h"
#include "content/public/browser/frame_tree_node_id.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/system/data_pipe_drainer.h"
#include "net/base/network_anonymization_key.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "url/gurl.h"

namespace network {
class SharedURLLoaderFactory;
}

namespace blink {
class URLLoaderThrottle;
}

namespace content {

class BrowserContext;
class PrefetchedSignedExchangeCacheAdapter;
class SignedExchangePrefetchHandler;

// A URLLoader for loading a prefetch request, including <link rel="prefetch">.
// It basically just keeps draining the data.
class PrefetchURLLoader : public network::mojom::URLLoader,
                          public network::mojom::URLLoaderClient,
                          public mojo::DataPipeDrainer::Client {
 public:
  using URLLoaderThrottlesGetter = base::RepeatingCallback<
      std::vector<std::unique_ptr<blink::URLLoaderThrottle>>()>;
  using RecursivePrefetchTokenGenerator =
      base::OnceCallback<base::UnguessableToken(
          const network::ResourceRequest&)>;

  // |network_anonymization_key| must be the NetworkAnonymizationKey that will
  // be used for the request (either matching
  // |resource_request.trusted_params|'s IsolationInfo, if trusted_params| is
  // non-null, or bound to |network_loader_factory|, otherwise).
  //
  // |url_loader_throttles_getter| may be used when a prefetch handler needs to
  // additionally create a request (e.g. for fetching certificate if the
  // prefetch was for a signed exchange).
  PrefetchURLLoader(
      int32_t request_id,
      uint32_t options,
      FrameTreeNodeId frame_tree_node_id,
      const network::ResourceRequest& resource_request,
      const net::NetworkAnonymizationKey& network_anonymization_key,
      mojo::PendingRemote<network::mojom::URLLoaderClient> client,
      const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
      scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory,
      URLLoaderThrottlesGetter url_loader_throttles_getter,
      BrowserContext* browser_context,
      scoped_refptr<PrefetchedSignedExchangeCache>
          prefetched_signed_exchange_cache,
      const std::string& accept_langs,
      RecursivePrefetchTokenGenerator recursive_prefetch_token_generator);

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

  ~PrefetchURLLoader() override;

  // Sends an empty response's body to |forwarding_client_|. If failed to create
  // a new data pipe, sends ERR_INSUFFICIENT_RESOURCES and closes the
  // connection, and returns false. Otherwise returns true.
  bool SendEmptyBody();

  void SendOnComplete(
      const network::URLLoaderCompletionStatus& completion_status);

 private:
  // network::mojom::URLLoader overrides:
  void FollowRedirect(
      const std::vector<std::string>& removed_headers,
      const net::HttpRequestHeaders& modified_headers,
      const net::HttpRequestHeaders& modified_cors_exempt_headers,
      const std::optional<GURL>& new_url) override;
  void SetPriority(net::RequestPriority priority,
                   int intra_priority_value) override;

  // network::mojom::URLLoaderClient overrides:
  void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
  void OnReceiveResponse(
      network::mojom::URLResponseHeadPtr head,
      mojo::ScopedDataPipeConsumerHandle body,
      std::optional<mojo_base::BigBuffer> cached_metadata) override;
  void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                         network::mojom::URLResponseHeadPtr head) override;
  void OnUploadProgress(int64_t current_position,
                        int64_t total_size,
                        base::OnceCallback<void()> callback) override;
  void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
  void OnComplete(const network::URLLoaderCompletionStatus& status) override;

  // mojo::DataPipeDrainer::Client overrides:
  // This just does nothing but keep reading.
  void OnDataAvailable(base::span<const uint8_t> data) override {}
  void OnDataComplete() override {}

  void OnNetworkConnectionError();

  const FrameTreeNodeId frame_tree_node_id_;

  // Set in the constructor and updated when redirected.
  network::ResourceRequest resource_request_;

  network::mojom::URLResponseHeadPtr response_;

  const net::NetworkAnonymizationKey network_anonymization_key_;

  scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory_;

  // For the actual request.
  mojo::Remote<network::mojom::URLLoader> loader_;
  mojo::Receiver<network::mojom::URLLoaderClient> client_receiver_{this};

  // To be a URLLoader for the client.
  mojo::Remote<network::mojom::URLLoaderClient> forwarding_client_;

  URLLoaderThrottlesGetter url_loader_throttles_getter_;

  std::unique_ptr<mojo::DataPipeDrainer> pipe_drainer_;

  std::unique_ptr<SignedExchangePrefetchHandler>
      signed_exchange_prefetch_handler_;

  // Used to store the prefetched signed exchanges to a
  // PrefetchedSignedExchangeCache.
  std::unique_ptr<PrefetchedSignedExchangeCacheAdapter>
      prefetched_signed_exchange_cache_adapter_;

  const std::string accept_langs_;

  RecursivePrefetchTokenGenerator recursive_prefetch_token_generator_;

  // TODO(kinuko): This value can become stale if the preference is updated.
  // Make this listen to the changes if it becomes a real concern.
  bool is_signed_exchange_handling_enabled_ = false;
};

}  // namespace content

#endif  // CONTENT_BROWSER_LOADER_PREFETCH_URL_LOADER_H_
