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

#ifndef COMPONENTS_CRONET_CRONET_URL_REQUEST_H_
#define COMPONENTS_CRONET_CRONET_URL_REQUEST_H_

#include <memory>
#include <string>

#include "base/callback.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "net/base/request_priority.h"
#include "net/url_request/url_request.h"
#include "url/gurl.h"

namespace net {
class HttpRequestHeaders;
enum LoadState;
class SSLCertRequestInfo;
class SSLInfo;
class UploadDataStream;
}  // namespace net

namespace cronet {

class CronetURLRequestContext;
class TestUtil;

// Wrapper around net::URLRequestContext.
// Created and configured from client thread. Start, ReadData, and Destroy are
// posted to network thread and all callbacks into the Callback() are
// done on the network thread. CronetUrlRequest client is expected to initiate
// the next step like FollowDeferredRedirect, ReadData or Destroy. Public
// methods can be called on any thread.
class CronetURLRequest {
 public:
  // Callback implemented by CronetURLRequest() caller and owned by
  // CronetURLRequest::NetworkTasks. All callback methods are invoked on network
  // thread.
  class Callback {
   public:
    virtual ~Callback() = default;

    // Invoked whenever a redirect is encountered. This will only be invoked
    // between the call to CronetURLRequest::Start() and
    // Callback::OnResponseStarted(). The body of the redirect response, if
    // it has one, will be ignored.
    //
    // The redirect will not be followed until
    // CronetURLRequest::FollowDeferredRedirect() method is called, either
    // synchronously or asynchronously.
    virtual void OnReceivedRedirect(const std::string& new_location,
                                    int http_status_code,
                                    const std::string& http_status_text,
                                    const net::HttpResponseHeaders* headers,
                                    bool was_cached,
                                    const std::string& negotiated_protocol,
                                    const std::string& proxy_server,
                                    int64_t received_byte_count) = 0;

    // Invoked when the final set of headers, after all redirects, is received.
    // Will only be invoked once for each request.
    //
    // With the exception of Callback::OnCanceled(),
    // no other Callback method will be invoked for the request,
    // including Callback::OnSucceeded() and Callback::OnFailed(), until
    // CronetUrlRequest::Read() is called to attempt to start reading the
    // response body.
    virtual void OnResponseStarted(int http_status_code,
                                   const std::string& http_status_text,
                                   const net::HttpResponseHeaders* headers,
                                   bool was_cached,
                                   const std::string& negotiated_protocol,
                                   const std::string& proxy_server) = 0;

    // Invoked whenever part of the response body has been read. Only part of
    // the buffer may be populated, even if the entire response body has not yet
    // been consumed.
    //
    // With the exception of Callback::OnCanceled(),
    // no other Callback method will be invoked for the request,
    // including Callback::OnSucceeded() and Callback::OnFailed(), until
    // CronetUrlRequest::Read() is called to attempt to continue reading the
    // response body.
    virtual void OnReadCompleted(scoped_refptr<net::IOBuffer> buffer,
                                 int bytes_read,
                                 int64_t received_byte_count) = 0;

    // Invoked when request is completed successfully.
    virtual void OnSucceeded(int64_t received_byte_count) = 0;

    // Invoked if request failed for any reason after CronetURLRequest::Start().
    // |net_error| provides information about the failure. |quic_error| is only
    // valid if |net_error| is net::QUIC_PROTOCOL_ERROR.
    virtual void OnError(int net_error,
                         int quic_error,
                         const std::string& error_string,
                         int64_t received_byte_count) = 0;

    // Invoked if request was canceled via CronetURLRequest::Start().
    virtual void OnCanceled() = 0;

    // Invoked when request is destroyed. Once invoked, no other Callback
    // methods will be invoked.
    virtual void OnDestroyed() = 0;

    // Invoked right before request is destroyed to report collected metrics if
    // |enable_metrics| is true in CronetURLRequest::CronetURLRequest().
    virtual void OnMetricsCollected(const base::Time& request_start_time,
                                    const base::TimeTicks& request_start,
                                    const base::TimeTicks& dns_start,
                                    const base::TimeTicks& dns_end,
                                    const base::TimeTicks& connect_start,
                                    const base::TimeTicks& connect_end,
                                    const base::TimeTicks& ssl_start,
                                    const base::TimeTicks& ssl_end,
                                    const base::TimeTicks& send_start,
                                    const base::TimeTicks& send_end,
                                    const base::TimeTicks& push_start,
                                    const base::TimeTicks& push_end,
                                    const base::TimeTicks& receive_headers_end,
                                    const base::TimeTicks& request_end,
                                    bool socket_reused,
                                    int64_t sent_bytes_count,
                                    int64_t received_bytes_count) = 0;
  };
  // Invoked in response to CronetURLRequest::GetStatus() to allow multiple
  // overlapping calls. The load states correspond to the lengthy periods of
  // time that a request load may be blocked and unable to make progress.
  using OnStatusCallback = base::OnceCallback<void(net::LoadState)>;

  // Bypasses cache if |disable_cache| is true. If context is not set up to
  // use cache, |disable_cache| has no effect. |disable_connection_migration|
  // causes connection migration to be disabled for this request if true. If
  // global connection migration flag is not enabled,
  // |disable_connection_migration| has no effect.
  CronetURLRequest(CronetURLRequestContext* context,
                   std::unique_ptr<Callback> callback,
                   const GURL& url,
                   net::RequestPriority priority,
                   bool disable_cache,
                   bool disable_connection_migration,
                   bool enable_metrics);

  // Methods called prior to Start are never called on network thread.

  // Sets the request method GET, POST etc.
  bool SetHttpMethod(const std::string& method);

  // Adds a header to the request before it starts.
  bool AddRequestHeader(const std::string& name, const std::string& value);

  // Adds a request body to the request before it starts.
  void SetUpload(std::unique_ptr<net::UploadDataStream> upload);

  // Starts the request.
  void Start();

  // GetStatus invokes |on_status_callback| on network thread to allow multiple
  // overlapping calls.
  void GetStatus(OnStatusCallback on_status_callback) const;

  // Follows redirect.
  void FollowDeferredRedirect();

  // Reads more data.
  bool ReadData(net::IOBuffer* buffer, int max_bytes);

  // Releases all resources for the request and deletes the object itself.
  // |send_on_canceled| indicates whether OnCanceled callback should be
  // issued to indicate when no more callbacks will be issued.
  void Destroy(bool send_on_canceled);

 private:
  friend class TestUtil;

  // Private destructor invoked fron NetworkTasks::Destroy() on network thread.
  ~CronetURLRequest();

  // NetworkTasks performs tasks on the network thread and owns objects that
  // live on the network thread.
  class NetworkTasks : public net::URLRequest::Delegate {
   public:
    // Invoked off the network thread.
    NetworkTasks(std::unique_ptr<Callback> callback,
                 const GURL& url,
                 net::RequestPriority priority,
                 int load_flags,
                 bool enable_metrics);

    // Invoked on the network thread.
    ~NetworkTasks() override;

    // Starts the request.
    void Start(CronetURLRequestContext* context,
               const std::string& method,
               std::unique_ptr<net::HttpRequestHeaders> request_headers,
               std::unique_ptr<net::UploadDataStream> upload);

    // Gets status of the requrest and invokes |on_status_callback| to allow
    // multiple overlapping calls.
    void GetStatus(OnStatusCallback on_status_callback) const;

    // Follows redirect.
    void FollowDeferredRedirect();

    // Reads more data.
    void ReadData(scoped_refptr<net::IOBuffer> read_buffer, int buffer_size);

    // Releases all resources for the request and deletes the |request|, which
    // owns |this|, so |this| is also deleted.
    // |send_on_canceled| indicates whether OnCanceled callback should be
    // issued to indicate when no more callbacks will be issued.
    void Destroy(CronetURLRequest* request, bool send_on_canceled);

   private:
    friend class TestUtil;

    // net::URLRequest::Delegate implementations:
    void OnReceivedRedirect(net::URLRequest* request,
                            const net::RedirectInfo& redirect_info,
                            bool* defer_redirect) override;
    void OnCertificateRequested(
        net::URLRequest* request,
        net::SSLCertRequestInfo* cert_request_info) override;
    void OnSSLCertificateError(net::URLRequest* request,
                               const net::SSLInfo& ssl_info,
                               bool fatal) override;
    void OnResponseStarted(net::URLRequest* request, int net_error) override;
    void OnReadCompleted(net::URLRequest* request, int bytes_read) override;

    // Report error and cancel request_adapter.
    void ReportError(net::URLRequest* request, int net_error);
    // Reports metrics collected.
    void MaybeReportMetrics();

    // Callback implemented by the client.
    std::unique_ptr<CronetURLRequest::Callback> callback_;

    const GURL initial_url_;
    const net::RequestPriority initial_priority_;
    const int initial_load_flags_;

    // Whether detailed metrics should be collected and reported.
    const bool enable_metrics_;
    // Whether metrics have been reported.
    bool metrics_reported_;

    scoped_refptr<net::IOBuffer> read_buffer_;
    std::unique_ptr<net::URLRequest> url_request_;

    THREAD_CHECKER(network_thread_checker_);
    DISALLOW_COPY_AND_ASSIGN(NetworkTasks);
  };

  CronetURLRequestContext* context_;
  // |network_tasks_| is invoked on network thread.
  NetworkTasks network_tasks_;

  // Request parameters set off network thread before Start().
  std::string initial_method_;
  std::unique_ptr<net::HttpRequestHeaders> initial_request_headers_;
  std::unique_ptr<net::UploadDataStream> upload_;

  DISALLOW_COPY_AND_ASSIGN(CronetURLRequest);
};

}  // namespace cronet

#endif  // COMPONENTS_CRONET_CRONET_URL_REQUEST_H_
