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

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <string>

#include "base/containers/circular_deque.h"
#include "base/containers/span.h"
#include "base/functional/callback.h"
#include "base/memory/weak_ptr.h"
#include "third_party/blink/public/web/web_associated_url_loader_client.h"

namespace blink {
class WebAssociatedURLLoader;
class WebString;
class WebURL;
class WebURLRequest;
struct WebAssociatedURLLoaderOptions;
}  // namespace blink

namespace net {
class SiteForCookies;
}  // namespace net

namespace chrome_pdf {

// Properties for making a URL request.
struct UrlRequest final {
  UrlRequest();
  UrlRequest(const UrlRequest& other);
  UrlRequest(UrlRequest&& other) noexcept;
  UrlRequest& operator=(const UrlRequest& other);
  UrlRequest& operator=(UrlRequest&& other) noexcept;
  ~UrlRequest();

  // Request URL.
  std::string url;

  // HTTP method.
  std::string method;

  // Whether to ignore redirects. By default, redirects are followed
  // automatically.
  bool ignore_redirects = false;

  // Custom referrer URL.
  std::string custom_referrer_url;

  // HTTP headers as a single string of `\n`-delimited key-value pairs.
  std::string headers;

  // Request body.
  std::string body;

  // Thresholds for throttling filling of the loader's internal buffer. Filling
  // will stop after exceeding the upper threshold, and resume after dropping
  // below the lower threshold.
  //
  // Default values taken from `ppapi/shared_impl/url_request_info_data.cc`. The
  // PDF viewer never changes the defaults in production, so these fields mostly
  // exist for testing purposes.
  size_t buffer_lower_threshold = 50 * 1000 * 1000;
  size_t buffer_upper_threshold = 100 * 1000 * 1000;
};

// Properties returned from a URL request. Does not include the response body.
struct UrlResponse final {
  UrlResponse();
  UrlResponse(const UrlResponse& other);
  UrlResponse(UrlResponse&& other) noexcept;
  UrlResponse& operator=(const UrlResponse& other);
  UrlResponse& operator=(UrlResponse&& other) noexcept;
  ~UrlResponse();

  // HTTP status code.
  int32_t status_code = 0;

  // HTTP headers as a single string of `\n`-delimited key-value pairs.
  std::string headers;
};

// A Blink URL loader. This implementation tries to emulate a combination of
// `content::PepperURLLoaderHost` and `ppapi::proxy::URLLoaderResource`.
class UrlLoader final : public blink::WebAssociatedURLLoaderClient {
 public:
  // Client interface required by `UrlLoader`. Instances should be passed using
  // weak pointers, as the loader can be shared, and may outlive the client.
  class Client {
   public:
    // Returns `true` if the client is still usable. The client may require
    // resources that can become unavailable, such as a local frame. Rather than
    // handling missing resources separately for each method, callers can just
    // verify validity once, before making any other calls.
    virtual bool IsValid() const = 0;

    // Completes `partial_url` using the current document.
    virtual blink::WebURL CompleteURL(
        const blink::WebString& partial_url) const = 0;

    // Gets the site-for-cookies for the current document.
    virtual net::SiteForCookies SiteForCookies() const = 0;

    // Sets the referrer on `request` to `referrer_url` using the current frame.
    virtual void SetReferrerForRequest(blink::WebURLRequest& request,
                                       const blink::WebURL& referrer_url) = 0;

    // Returns a new `blink::WebAssociatedURLLoader` from the current frame.
    virtual std::unique_ptr<blink::WebAssociatedURLLoader>
    CreateAssociatedURLLoader(
        const blink::WebAssociatedURLLoaderOptions& options) = 0;

   protected:
    ~Client() = default;
  };

  explicit UrlLoader(base::WeakPtr<Client> client);
  UrlLoader(const UrlLoader&) = delete;
  UrlLoader& operator=(const UrlLoader&) = delete;
  ~UrlLoader() override;

  // Mimic `pp::URLLoader`:
  void Open(const UrlRequest& request, base::OnceCallback<void(int)> callback);
  void ReadResponseBody(base::span<char> buffer,
                        base::OnceCallback<void(int)> callback);
  void Close();

  // Returns the URL response (not including the body). Only valid after
  // `Open()` completes.
  const UrlResponse& response() const { return response_; }

  // blink::WebAssociatedURLLoaderClient:
  bool WillFollowRedirect(
      const blink::WebURL& new_url,
      const blink::WebURLResponse& redirect_response) override;
  void DidSendData(uint64_t bytes_sent,
                   uint64_t total_bytes_to_be_sent) override;
  void DidReceiveResponse(const blink::WebURLResponse& response) override;
  void DidDownloadData(uint64_t data_length) override;
  void DidReceiveData(const char* data, int data_length) override;
  void DidFinishLoading() override;
  void DidFail(const blink::WebURLError& error) override;

 private:
  enum class LoadingState {
    // Before calling `Open()`.
    kWaitingToOpen,

    // After calling `Open()`, but before `DidReceiveResponse()` or `DidFail()`.
    kOpening,

    // After `DidReceiveResponse()`, but before `DidFinishLoading()` or
    // `DidFail()`. Zero or more calls allowed to `DidReceiveData()`.
    kStreamingData,

    // After `DidFinishLoading()` or `DidFail()`, or forced by `Close()`.
    // Details about how the load completed are in `complete_result_`.
    kLoadComplete,
  };

  // Aborts the load with `result`. Runs callback if pending.
  void AbortLoad(int32_t result);

  // Runs callback for `ReadResponseBody()` if pending.
  void RunReadCallback();

  void SetLoadComplete(int32_t result);

  base::WeakPtr<Client> client_;

  LoadingState state_ = LoadingState::kWaitingToOpen;
  int32_t complete_result_ = 0;

  std::unique_ptr<blink::WebAssociatedURLLoader> blink_loader_;

  bool ignore_redirects_ = false;
  base::OnceCallback<void(int)> open_callback_;

  UrlResponse response_;

  // Thresholds control buffer throttling, as defined in `UrlRequest`.
  size_t buffer_lower_threshold_ = 0;
  size_t buffer_upper_threshold_ = 0;
  bool deferring_loading_ = false;
  base::circular_deque<char> buffer_;

  base::OnceCallback<void(int)> read_callback_;
  base::span<char> client_buffer_;
};

}  // namespace chrome_pdf

#endif  // PDF_LOADER_URL_LOADER_H_
