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

#include "components/cronet/native/url_request.h"

#include <utility>
#include <vector>

#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "components/cronet/cronet_upload_data_stream.h"
#include "components/cronet/native/engine.h"
#include "components/cronet/native/generated/cronet.idl_impl_struct.h"
#include "components/cronet/native/include/cronet_c.h"
#include "components/cronet/native/io_buffer_with_cronet_buffer.h"
#include "components/cronet/native/native_metrics_util.h"
#include "components/cronet/native/runnables.h"
#include "components/cronet/native/upload_data_sink.h"
#include "net/base/io_buffer.h"
#include "net/base/load_states.h"

namespace {

using RequestFinishedInfo = base::RefCountedData<Cronet_RequestFinishedInfo>;
using UrlResponseInfo = base::RefCountedData<Cronet_UrlResponseInfo>;
using CronetError = base::RefCountedData<Cronet_Error>;

template <typename T>
T* GetData(scoped_refptr<base::RefCountedData<T>> ptr) {
  return ptr == nullptr ? nullptr : &ptr->data;
}

net::RequestPriority ConvertRequestPriority(
    Cronet_UrlRequestParams_REQUEST_PRIORITY priority) {
  switch (priority) {
    case Cronet_UrlRequestParams_REQUEST_PRIORITY_REQUEST_PRIORITY_IDLE:
      return net::IDLE;
    case Cronet_UrlRequestParams_REQUEST_PRIORITY_REQUEST_PRIORITY_LOWEST:
      return net::LOWEST;
    case Cronet_UrlRequestParams_REQUEST_PRIORITY_REQUEST_PRIORITY_LOW:
      return net::LOW;
    case Cronet_UrlRequestParams_REQUEST_PRIORITY_REQUEST_PRIORITY_MEDIUM:
      return net::MEDIUM;
    case Cronet_UrlRequestParams_REQUEST_PRIORITY_REQUEST_PRIORITY_HIGHEST:
      return net::HIGHEST;
  }
  return net::DEFAULT_PRIORITY;
}

net::Idempotency ConvertIdempotency(
    Cronet_UrlRequestParams_IDEMPOTENCY idempotency) {
  switch (idempotency) {
    case Cronet_UrlRequestParams_IDEMPOTENCY_DEFAULT_IDEMPOTENCY:
      return net::DEFAULT_IDEMPOTENCY;
    case Cronet_UrlRequestParams_IDEMPOTENCY_IDEMPOTENT:
      return net::IDEMPOTENT;
    case Cronet_UrlRequestParams_IDEMPOTENCY_NOT_IDEMPOTENT:
      return net::NOT_IDEMPOTENT;
  }
  return net::DEFAULT_IDEMPOTENCY;
}

scoped_refptr<UrlResponseInfo> CreateCronet_UrlResponseInfo(
    const std::vector<std::string>& url_chain,
    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) {
  auto response_info = base::MakeRefCounted<UrlResponseInfo>();
  response_info->data.url = url_chain.back();
  response_info->data.url_chain = url_chain;
  response_info->data.http_status_code = http_status_code;
  response_info->data.http_status_text = http_status_text;
  // |headers| could be nullptr.
  if (headers != nullptr) {
    size_t iter = 0;
    std::string header_name;
    std::string header_value;
    while (headers->EnumerateHeaderLines(&iter, &header_name, &header_value)) {
      Cronet_HttpHeader header;
      header.name = header_name;
      header.value = header_value;
      response_info->data.all_headers_list.push_back(std::move(header));
    }
  }
  response_info->data.was_cached = was_cached;
  response_info->data.negotiated_protocol = negotiated_protocol;
  response_info->data.proxy_server = proxy_server;
  response_info->data.received_byte_count = received_byte_count;
  return response_info;
}

Cronet_Error_ERROR_CODE NetErrorToCronetErrorCode(int net_error) {
  switch (net_error) {
    case net::ERR_NAME_NOT_RESOLVED:
      return Cronet_Error_ERROR_CODE_ERROR_HOSTNAME_NOT_RESOLVED;
    case net::ERR_INTERNET_DISCONNECTED:
      return Cronet_Error_ERROR_CODE_ERROR_INTERNET_DISCONNECTED;
    case net::ERR_NETWORK_CHANGED:
      return Cronet_Error_ERROR_CODE_ERROR_NETWORK_CHANGED;
    case net::ERR_TIMED_OUT:
      return Cronet_Error_ERROR_CODE_ERROR_TIMED_OUT;
    case net::ERR_CONNECTION_CLOSED:
      return Cronet_Error_ERROR_CODE_ERROR_CONNECTION_CLOSED;
    case net::ERR_CONNECTION_TIMED_OUT:
      return Cronet_Error_ERROR_CODE_ERROR_CONNECTION_TIMED_OUT;
    case net::ERR_CONNECTION_REFUSED:
      return Cronet_Error_ERROR_CODE_ERROR_CONNECTION_REFUSED;
    case net::ERR_CONNECTION_RESET:
      return Cronet_Error_ERROR_CODE_ERROR_CONNECTION_RESET;
    case net::ERR_ADDRESS_UNREACHABLE:
      return Cronet_Error_ERROR_CODE_ERROR_ADDRESS_UNREACHABLE;
    case net::ERR_QUIC_PROTOCOL_ERROR:
      return Cronet_Error_ERROR_CODE_ERROR_QUIC_PROTOCOL_FAILED;
    default:
      return Cronet_Error_ERROR_CODE_ERROR_OTHER;
  }
}

bool IsCronetErrorImmediatelyRetryable(Cronet_Error_ERROR_CODE error_code) {
  switch (error_code) {
    case Cronet_Error_ERROR_CODE_ERROR_HOSTNAME_NOT_RESOLVED:
    case Cronet_Error_ERROR_CODE_ERROR_INTERNET_DISCONNECTED:
    case Cronet_Error_ERROR_CODE_ERROR_CONNECTION_REFUSED:
    case Cronet_Error_ERROR_CODE_ERROR_ADDRESS_UNREACHABLE:
    case Cronet_Error_ERROR_CODE_ERROR_OTHER:
    default:
      return false;
    case Cronet_Error_ERROR_CODE_ERROR_NETWORK_CHANGED:
    case Cronet_Error_ERROR_CODE_ERROR_TIMED_OUT:
    case Cronet_Error_ERROR_CODE_ERROR_CONNECTION_CLOSED:
    case Cronet_Error_ERROR_CODE_ERROR_CONNECTION_TIMED_OUT:
    case Cronet_Error_ERROR_CODE_ERROR_CONNECTION_RESET:
      return true;
  }
}

scoped_refptr<CronetError> CreateCronet_Error(int net_error,
                                              int quic_error,
                                              const std::string& error_string) {
  auto error = base::MakeRefCounted<CronetError>();
  error->data.error_code = NetErrorToCronetErrorCode(net_error);
  error->data.message = error_string;
  error->data.internal_error_code = net_error;
  error->data.quic_detailed_error_code = quic_error;
  error->data.immediately_retryable =
      IsCronetErrorImmediatelyRetryable(error->data.error_code);
  return error;
}

#if DCHECK_IS_ON()
// Runnable used to verify that Executor calls Cronet_Runnable_Destroy().
class VerifyDestructionRunnable : public Cronet_Runnable {
 public:
  VerifyDestructionRunnable(base::WaitableEvent* destroyed)
      : destroyed_(destroyed) {}

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

  // Signal event indicating Runnable was properly Destroyed.
  ~VerifyDestructionRunnable() override { destroyed_->Signal(); }

  void Run() override {}

 private:
  // Event indicating destructor is called.
  const raw_ptr<base::WaitableEvent> destroyed_;
};
#endif  // DCHECK_IS_ON()

// Convert net::LoadState to Cronet_UrlRequestStatusListener_Status.
Cronet_UrlRequestStatusListener_Status ConvertLoadState(
    net::LoadState load_state) {
  switch (load_state) {
    case net::LOAD_STATE_IDLE:
      return Cronet_UrlRequestStatusListener_Status_IDLE;

    case net::LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL:
      return Cronet_UrlRequestStatusListener_Status_WAITING_FOR_STALLED_SOCKET_POOL;

    case net::LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET:
      return Cronet_UrlRequestStatusListener_Status_WAITING_FOR_AVAILABLE_SOCKET;

    case net::LOAD_STATE_WAITING_FOR_DELEGATE:
      return Cronet_UrlRequestStatusListener_Status_WAITING_FOR_DELEGATE;

    case net::LOAD_STATE_WAITING_FOR_CACHE:
      return Cronet_UrlRequestStatusListener_Status_WAITING_FOR_CACHE;

    case net::LOAD_STATE_DOWNLOADING_PAC_FILE:
      return Cronet_UrlRequestStatusListener_Status_DOWNLOADING_PAC_FILE;

    case net::LOAD_STATE_RESOLVING_PROXY_FOR_URL:
      return Cronet_UrlRequestStatusListener_Status_RESOLVING_PROXY_FOR_URL;

    case net::LOAD_STATE_RESOLVING_HOST_IN_PAC_FILE:
      return Cronet_UrlRequestStatusListener_Status_RESOLVING_HOST_IN_PAC_FILE;

    case net::LOAD_STATE_ESTABLISHING_PROXY_TUNNEL:
      return Cronet_UrlRequestStatusListener_Status_ESTABLISHING_PROXY_TUNNEL;

    case net::LOAD_STATE_RESOLVING_HOST:
      return Cronet_UrlRequestStatusListener_Status_RESOLVING_HOST;

    case net::LOAD_STATE_CONNECTING:
      return Cronet_UrlRequestStatusListener_Status_CONNECTING;

    case net::LOAD_STATE_SSL_HANDSHAKE:
      return Cronet_UrlRequestStatusListener_Status_SSL_HANDSHAKE;

    case net::LOAD_STATE_SENDING_REQUEST:
      return Cronet_UrlRequestStatusListener_Status_SENDING_REQUEST;

    case net::LOAD_STATE_WAITING_FOR_RESPONSE:
      return Cronet_UrlRequestStatusListener_Status_WAITING_FOR_RESPONSE;

    case net::LOAD_STATE_READING_RESPONSE:
      return Cronet_UrlRequestStatusListener_Status_READING_RESPONSE;

    default:
      // A load state is retrieved but there is no corresponding
      // request status. This most likely means that the mapping is
      // incorrect.
      CHECK(false);
      return Cronet_UrlRequestStatusListener_Status_INVALID;
  }
}

}  // namespace

namespace cronet {

// NetworkTasks is owned by CronetURLRequest. It is constructed on client
// thread, but invoked and deleted on the network thread.
class Cronet_UrlRequestImpl::NetworkTasks : public CronetURLRequest::Callback {
 public:
  NetworkTasks(const std::string& url, Cronet_UrlRequestImpl* url_request);

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

  ~NetworkTasks() override = default;

  // Callback function used for GetStatus().
  void OnStatus(Cronet_UrlRequestStatusListenerPtr listener,
                net::LoadState load_state);

 private:
  // CronetURLRequest::Callback implementation:
  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) override;
  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,
                         int64_t received_byte_count) override;
  void OnReadCompleted(scoped_refptr<net::IOBuffer> buffer,
                       int bytes_read,
                       int64_t received_byte_count) override;
  void OnSucceeded(int64_t received_byte_count) override;
  void OnError(int net_error,
               int quic_error,
               const std::string& error_string,
               int64_t received_byte_count) override;
  void OnCanceled() override;
  void OnDestroyed() override;
  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,
                          bool quic_connection_migration_attempted,
                          bool quic_connection_migration_successful)
      LOCKS_EXCLUDED(url_request_->lock_) override;

  // The UrlRequest which owns context that owns the callback.
  const raw_ptr<Cronet_UrlRequestImpl, AcrossTasksDanglingUntriaged>
      url_request_ = nullptr;

  // URL chain contains the URL currently being requested, and
  // all URLs previously requested. New URLs are added before
  // Cronet_UrlRequestCallback::OnRedirectReceived is called.
  std::vector<std::string> url_chain_;

  // Set to true when OnCanceled/OnSucceeded/OnFailed is posted.
  // When true it is unsafe to attempt to post other callbacks
  // like OnStatus because the request may be destroyed.
  bool final_callback_posted_ = false;

  // All methods except constructor are invoked on the network thread.
  THREAD_CHECKER(network_thread_checker_);
};

Cronet_UrlRequestImpl::Cronet_UrlRequestImpl() = default;

Cronet_UrlRequestImpl::~Cronet_UrlRequestImpl() {
  base::AutoLock lock(lock_);
  // Only request that has never started is allowed to exist at this point.
  // The app must wait for OnSucceeded / OnFailed / OnCanceled  callback before
  // destroying |this|.
  if (request_) {
    CHECK(!started_);
    DestroyRequestUnlessDoneLocked(
        Cronet_RequestFinishedInfo_FINISHED_REASON_SUCCEEDED);
  }
}

Cronet_RESULT Cronet_UrlRequestImpl::InitWithParams(
    Cronet_EnginePtr engine,
    Cronet_String url,
    Cronet_UrlRequestParamsPtr params,
    Cronet_UrlRequestCallbackPtr callback,
    Cronet_ExecutorPtr executor) {
  CHECK(engine);
  engine_ = reinterpret_cast<Cronet_EngineImpl*>(engine);
  if (!url || std::string(url).empty())
    return engine_->CheckResult(Cronet_RESULT_NULL_POINTER_URL);
  if (!params)
    return engine_->CheckResult(Cronet_RESULT_NULL_POINTER_PARAMS);
  if (!callback)
    return engine_->CheckResult(Cronet_RESULT_NULL_POINTER_CALLBACK);
  if (!executor)
    return engine_->CheckResult(Cronet_RESULT_NULL_POINTER_EXECUTOR);

  VLOG(1) << "New Cronet_UrlRequest: " << url;

  base::AutoLock lock(lock_);
  if (request_) {
    return engine_->CheckResult(
        Cronet_RESULT_ILLEGAL_STATE_REQUEST_ALREADY_INITIALIZED);
  }

  callback_ = callback;
  executor_ = executor;

  if (params->request_finished_listener != nullptr &&
      params->request_finished_executor == nullptr) {
    return engine_->CheckResult(
        Cronet_RESULT_NULL_POINTER_REQUEST_FINISHED_INFO_LISTENER_EXECUTOR);
  }

  request_finished_listener_ = params->request_finished_listener;
  request_finished_executor_ = params->request_finished_executor;
  // Copy, don't move -- this function isn't allowed to change |params|.
  annotations_ = params->annotations;

  auto network_tasks = std::make_unique<NetworkTasks>(url, this);
  network_tasks_ = network_tasks.get();

  request_ = new CronetURLRequest(
      engine_->cronet_url_request_context(), std::move(network_tasks),
      GURL(url), ConvertRequestPriority(params->priority),
      params->disable_cache, true /* params->disableConnectionMigration */,
      // TODO(pauljensen): Consider exposing TrafficStats API via C++ API.
      false /* traffic_stats_tag_set */, 0 /* traffic_stats_tag */,
      false /* traffic_stats_uid_set */, 0 /* traffic_stats_uid */,
      ConvertIdempotency(params->idempotency));

  if (params->upload_data_provider) {
    upload_data_sink_ = std::make_unique<Cronet_UploadDataSinkImpl>(
        this, params->upload_data_provider,
        params->upload_data_provider_executor
            ? params->upload_data_provider_executor
            : executor);
    upload_data_sink_->InitRequest(request_);
    request_->SetHttpMethod("POST");
  }

  if (!params->http_method.empty() &&
      !request_->SetHttpMethod(params->http_method)) {
    return engine_->CheckResult(
        Cronet_RESULT_ILLEGAL_ARGUMENT_INVALID_HTTP_METHOD);
  }

  for (const auto& request_header : params->request_headers) {
    if (request_header.name.empty())
      return engine_->CheckResult(Cronet_RESULT_NULL_POINTER_HEADER_NAME);
    if (request_header.value.empty())
      return engine_->CheckResult(Cronet_RESULT_NULL_POINTER_HEADER_VALUE);
    if (!request_->AddRequestHeader(request_header.name,
                                    request_header.value)) {
      return engine_->CheckResult(
          Cronet_RESULT_ILLEGAL_ARGUMENT_INVALID_HTTP_HEADER);
    }
  }
  return engine_->CheckResult(Cronet_RESULT_SUCCESS);
}

Cronet_RESULT Cronet_UrlRequestImpl::Start() {
  base::AutoLock lock(lock_);
  if (started_) {
    return engine_->CheckResult(
        Cronet_RESULT_ILLEGAL_STATE_REQUEST_ALREADY_STARTED);
  }
  if (!request_) {
    return engine_->CheckResult(
        Cronet_RESULT_ILLEGAL_STATE_REQUEST_NOT_INITIALIZED);
  }
#if DCHECK_IS_ON()
  Cronet_Executor_Execute(executor_,
                          new VerifyDestructionRunnable(&runnable_destroyed_));
#endif  // DCHECK_IS_ON()
  request_->Start();
  started_ = true;
  return engine_->CheckResult(Cronet_RESULT_SUCCESS);
}

Cronet_RESULT Cronet_UrlRequestImpl::FollowRedirect() {
  base::AutoLock lock(lock_);
  if (!waiting_on_redirect_) {
    return engine_->CheckResult(
        Cronet_RESULT_ILLEGAL_STATE_UNEXPECTED_REDIRECT);
  }
  waiting_on_redirect_ = false;
  if (!IsDoneLocked())
    request_->FollowDeferredRedirect();
  return engine_->CheckResult(Cronet_RESULT_SUCCESS);
}

Cronet_RESULT Cronet_UrlRequestImpl::Read(Cronet_BufferPtr buffer) {
  base::AutoLock lock(lock_);
  if (!waiting_on_read_)
    return engine_->CheckResult(Cronet_RESULT_ILLEGAL_STATE_UNEXPECTED_READ);
  waiting_on_read_ = false;
  if (IsDoneLocked()) {
    Cronet_Buffer_Destroy(buffer);
    return engine_->CheckResult(Cronet_RESULT_SUCCESS);
  }
  // Create IOBuffer that will own |buffer| while it is used by |request_|.
  net::IOBuffer* io_buffer = new IOBufferWithCronet_Buffer(buffer);
  if (request_->ReadData(io_buffer, Cronet_Buffer_GetSize(buffer)))
    return engine_->CheckResult(Cronet_RESULT_SUCCESS);
  return engine_->CheckResult(Cronet_RESULT_ILLEGAL_STATE_READ_FAILED);
}

void Cronet_UrlRequestImpl::Cancel() {
  base::AutoLock lock(lock_);
  if (started_) {
    // If request has posted callbacks to client executor, then it is possible
    // that |request_| will be destroyed before callback is executed. The
    // callback runnable uses IsDone() to avoid calling client callback in this
    // case.
    DestroyRequestUnlessDoneLocked(
        Cronet_RequestFinishedInfo_FINISHED_REASON_CANCELED);
  }
}

bool Cronet_UrlRequestImpl::IsDone() {
  base::AutoLock lock(lock_);
  return IsDoneLocked();
}

bool Cronet_UrlRequestImpl::IsDoneLocked() const {
  lock_.AssertAcquired();
  return started_ && request_ == nullptr;
}

bool Cronet_UrlRequestImpl::DestroyRequestUnlessDone(
    Cronet_RequestFinishedInfo_FINISHED_REASON finished_reason) {
  base::AutoLock lock(lock_);
  return DestroyRequestUnlessDoneLocked(finished_reason);
}

bool Cronet_UrlRequestImpl::DestroyRequestUnlessDoneLocked(
    Cronet_RequestFinishedInfo_FINISHED_REASON finished_reason) {
  lock_.AssertAcquired();
  if (request_ == nullptr)
    return true;
  DCHECK(error_ == nullptr ||
         finished_reason == Cronet_RequestFinishedInfo_FINISHED_REASON_FAILED);
  request_->Destroy(finished_reason ==
                    Cronet_RequestFinishedInfo_FINISHED_REASON_CANCELED);
  // Request can no longer be used as CronetURLRequest::Destroy() will
  // eventually delete |request_| from the network thread, so setting |request_|
  // to nullptr doesn't introduce a memory leak.
  request_ = nullptr;
  return false;
}

void Cronet_UrlRequestImpl::GetStatus(
    Cronet_UrlRequestStatusListenerPtr listener) {
  {
    base::AutoLock lock(lock_);
    if (started_ && request_) {
      status_listeners_.insert(listener);
      // UnsafeDanglingUntriaged triggered by test:
      // UrlRequestTest.GetStatus
      // TODO(crbug.com/40061562): Remove `UnsafeDanglingUntriaged`
      request_->GetStatus(
          base::BindOnce(&Cronet_UrlRequestImpl::NetworkTasks::OnStatus,
                         base::Unretained(network_tasks_),
                         base::UnsafeDanglingUntriaged(listener)));
      return;
    }
  }
  PostTaskToExecutor(
      base::BindOnce(Cronet_UrlRequestStatusListener_OnStatus, listener,
                     Cronet_UrlRequestStatusListener_Status_INVALID));
}

void Cronet_UrlRequestImpl::PostCallbackOnFailedToExecutor() {
  PostTaskToExecutor(base::BindOnce(
      &Cronet_UrlRequestImpl::InvokeCallbackOnFailed, base::Unretained(this)));
}

void Cronet_UrlRequestImpl::OnUploadDataProviderError(
    const std::string& error_message) {
  base::AutoLock lock(lock_);
  // If |error_| is not nullptr, that means that another network error is
  // already reported.
  if (error_)
    return;
  error_ = CreateCronet_Error(
      0, 0, "Failure from UploadDataProvider: " + error_message);
  error_->data.error_code = Cronet_Error_ERROR_CODE_ERROR_CALLBACK;

  request_->MaybeReportMetricsAndRunCallback(
      base::BindOnce(&Cronet_UrlRequestImpl::PostCallbackOnFailedToExecutor,
                     base::Unretained(this)));
}

void Cronet_UrlRequestImpl::PostTaskToExecutor(base::OnceClosure task) {
  Cronet_RunnablePtr runnable =
      new cronet::OnceClosureRunnable(std::move(task));
  // |runnable| is passed to executor, which destroys it after execution.
  Cronet_Executor_Execute(executor_, runnable);
}

void Cronet_UrlRequestImpl::InvokeCallbackOnRedirectReceived(
    const std::string& new_location) {
  if (IsDone())
    return;
  Cronet_UrlRequestCallback_OnRedirectReceived(
      callback_, this, GetData(response_info_), new_location.c_str());
}

void Cronet_UrlRequestImpl::InvokeCallbackOnResponseStarted() {
  if (IsDone())
    return;
#if DCHECK_IS_ON()
  // Verify that Executor calls Cronet_Runnable_Destroy().
  if (!runnable_destroyed_.TimedWait(base::Seconds(5))) {
    LOG(ERROR) << "Cronet Executor didn't call Cronet_Runnable_Destroy() in "
                  "5s; still waiting.";
    runnable_destroyed_.Wait();
  }
#endif  // DCHECK_IS_ON()
  Cronet_UrlRequestCallback_OnResponseStarted(callback_, this,
                                              GetData(response_info_));
}

void Cronet_UrlRequestImpl::InvokeCallbackOnReadCompleted(
    std::unique_ptr<Cronet_Buffer> cronet_buffer,
    int bytes_read) {
  if (IsDone())
    return;
  Cronet_UrlRequestCallback_OnReadCompleted(
      callback_, this, GetData(response_info_), cronet_buffer.release(),
      bytes_read);
}

void Cronet_UrlRequestImpl::InvokeCallbackOnSucceeded() {
  if (DestroyRequestUnlessDone(
          Cronet_RequestFinishedInfo_FINISHED_REASON_SUCCEEDED)) {
    return;
  }
  InvokeAllStatusListeners();
  MaybeReportMetrics(Cronet_RequestFinishedInfo_FINISHED_REASON_SUCCEEDED);
  Cronet_UrlRequestCallback_OnSucceeded(callback_, this,
                                        GetData(response_info_));
  // |this| may have been deleted here.
}

void Cronet_UrlRequestImpl::InvokeCallbackOnFailed() {
  if (DestroyRequestUnlessDone(
          Cronet_RequestFinishedInfo_FINISHED_REASON_FAILED)) {
    return;
  }
  InvokeAllStatusListeners();
  MaybeReportMetrics(Cronet_RequestFinishedInfo_FINISHED_REASON_FAILED);
  Cronet_UrlRequestCallback_OnFailed(callback_, this, GetData(response_info_),
                                     GetData(error_));
  // |this| may have been deleted here.
}

void Cronet_UrlRequestImpl::InvokeCallbackOnCanceled() {
  InvokeAllStatusListeners();
  MaybeReportMetrics(Cronet_RequestFinishedInfo_FINISHED_REASON_CANCELED);
  Cronet_UrlRequestCallback_OnCanceled(callback_, this,
                                       GetData(response_info_));
  // |this| may have been deleted here.
}

void Cronet_UrlRequestImpl::InvokeAllStatusListeners() {
  std::unordered_multiset<Cronet_UrlRequestStatusListenerPtr> status_listeners;
  {
    base::AutoLock lock(lock_);
    // Verify the request has already been destroyed, which ensures no more
    // status listeners can be added.
    DCHECK(!request_);
    status_listeners.swap(status_listeners_);
  }
  for (Cronet_UrlRequestStatusListener* status_listener : status_listeners) {
    Cronet_UrlRequestStatusListener_OnStatus(
        status_listener, Cronet_UrlRequestStatusListener_Status_INVALID);
  }
#if DCHECK_IS_ON()
  // Verify no status listeners added during OnStatus() callbacks.
  base::AutoLock lock(lock_);
  DCHECK(status_listeners_.empty());
#endif  // DCHECK_IS_ON()
}

void Cronet_UrlRequestImpl::MaybeReportMetrics(
    Cronet_RequestFinishedInfo_FINISHED_REASON finished_reason) {
  if (request_finished_info_ == nullptr)
    return;
  request_finished_info_->data.annotations = std::move(annotations_);
  request_finished_info_->data.finished_reason = finished_reason;

  engine_->ReportRequestFinished(request_finished_info_, response_info_,
                                 error_);
  if (request_finished_listener_ != nullptr) {
    DCHECK(request_finished_executor_ != nullptr);
    // Execute() owns and deletes the runnable.
    request_finished_executor_->Execute(
        new cronet::OnceClosureRunnable(base::BindOnce(
            [](Cronet_RequestFinishedInfoListenerPtr request_finished_listener,
               scoped_refptr<RequestFinishedInfo> request_finished_info,
               scoped_refptr<UrlResponseInfo> response_info,
               scoped_refptr<CronetError> error) {
              request_finished_listener->OnRequestFinished(
                  GetData(request_finished_info), GetData(response_info),
                  GetData(error));
            },
            request_finished_listener_, request_finished_info_, response_info_,
            error_)));
  }
}

Cronet_UrlRequestImpl::NetworkTasks::NetworkTasks(
    const std::string& url,
    Cronet_UrlRequestImpl* url_request)
    : url_request_(url_request), url_chain_({url}) {
  DETACH_FROM_THREAD(network_thread_checker_);
  DCHECK(url_request);
}

void Cronet_UrlRequestImpl::NetworkTasks::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) {
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);
  {
    base::AutoLock lock(url_request_->lock_);
    url_request_->waiting_on_redirect_ = true;
    url_request_->response_info_ = CreateCronet_UrlResponseInfo(
        url_chain_, http_status_code, http_status_text, headers, was_cached,
        negotiated_protocol, proxy_server, received_byte_count);
  }

  // Have to do this after creating responseInfo.
  url_chain_.push_back(new_location);

  // Invoke Cronet_UrlRequestCallback_OnRedirectReceived on client executor.
  url_request_->PostTaskToExecutor(
      base::BindOnce(&Cronet_UrlRequestImpl::InvokeCallbackOnRedirectReceived,
                     base::Unretained(url_request_), new_location));
}

void Cronet_UrlRequestImpl::NetworkTasks::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,
    int64_t received_byte_count) {
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);
  {
    base::AutoLock lock(url_request_->lock_);
    url_request_->waiting_on_read_ = true;
    url_request_->response_info_ = CreateCronet_UrlResponseInfo(
        url_chain_, http_status_code, http_status_text, headers, was_cached,
        negotiated_protocol, proxy_server, received_byte_count);
  }

  if (url_request_->upload_data_sink_)
    url_request_->upload_data_sink_->PostCloseToExecutor();

  // Invoke Cronet_UrlRequestCallback_OnResponseStarted on client executor.
  url_request_->PostTaskToExecutor(
      base::BindOnce(&Cronet_UrlRequestImpl::InvokeCallbackOnResponseStarted,
                     base::Unretained(url_request_)));
}

void Cronet_UrlRequestImpl::NetworkTasks::OnReadCompleted(
    scoped_refptr<net::IOBuffer> buffer,
    int bytes_read,
    int64_t received_byte_count) {
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);
  IOBufferWithCronet_Buffer* io_buffer =
      reinterpret_cast<IOBufferWithCronet_Buffer*>(buffer.get());
  std::unique_ptr<Cronet_Buffer> cronet_buffer(io_buffer->Release());
  {
    base::AutoLock lock(url_request_->lock_);
    url_request_->waiting_on_read_ = true;
    url_request_->response_info_->data.received_byte_count =
        received_byte_count;
  }

  // Invoke Cronet_UrlRequestCallback_OnReadCompleted on client executor.
  url_request_->PostTaskToExecutor(base::BindOnce(
      &Cronet_UrlRequestImpl::InvokeCallbackOnReadCompleted,
      base::Unretained(url_request_), std::move(cronet_buffer), bytes_read));
}

void Cronet_UrlRequestImpl::NetworkTasks::OnSucceeded(
    int64_t received_byte_count) {
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);
  {
    base::AutoLock lock(url_request_->lock_);
    url_request_->response_info_->data.received_byte_count =
        received_byte_count;
  }

  // Invoke Cronet_UrlRequestCallback_OnSucceeded on client executor.
  url_request_->PostTaskToExecutor(
      base::BindOnce(&Cronet_UrlRequestImpl::InvokeCallbackOnSucceeded,
                     base::Unretained(url_request_)));
  final_callback_posted_ = true;
}

void Cronet_UrlRequestImpl::NetworkTasks::OnError(
    int net_error,
    int quic_error,
    const std::string& error_string,
    int64_t received_byte_count) {
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);
  {
    base::AutoLock lock(url_request_->lock_);
    if (url_request_->response_info_)
      url_request_->response_info_->data.received_byte_count =
          received_byte_count;
    url_request_->error_ =
        CreateCronet_Error(net_error, quic_error, error_string);
  }

  if (url_request_->upload_data_sink_)
    url_request_->upload_data_sink_->PostCloseToExecutor();

  // Invoke Cronet_UrlRequestCallback_OnFailed on client executor.
  url_request_->PostTaskToExecutor(
      base::BindOnce(&Cronet_UrlRequestImpl::InvokeCallbackOnFailed,
                     base::Unretained(url_request_)));
  final_callback_posted_ = true;
}

void Cronet_UrlRequestImpl::NetworkTasks::OnCanceled() {
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);
  if (url_request_->upload_data_sink_)
    url_request_->upload_data_sink_->PostCloseToExecutor();

  // Invoke Cronet_UrlRequestCallback_OnCanceled on client executor.
  url_request_->PostTaskToExecutor(
      base::BindOnce(&Cronet_UrlRequestImpl::InvokeCallbackOnCanceled,
                     base::Unretained(url_request_)));
  final_callback_posted_ = true;
}

void Cronet_UrlRequestImpl::NetworkTasks::OnDestroyed() {
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);
  DCHECK(url_request_);
}

void Cronet_UrlRequestImpl::NetworkTasks::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,
    bool,  // quic_connection_migration_attempted
    bool   // quic_connection_migration_successful
) {
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);
  base::AutoLock lock(url_request_->lock_);
  DCHECK_EQ(url_request_->request_finished_info_, nullptr)
      << "Metrics collection should only happen once.";
  url_request_->request_finished_info_ =
      base::MakeRefCounted<RequestFinishedInfo>();
  auto& metrics = url_request_->request_finished_info_->data.metrics;
  metrics.emplace();
  using native_metrics_util::ConvertTime;
  ConvertTime(request_start, request_start, request_start_time,
              &metrics->request_start);
  ConvertTime(dns_start, request_start, request_start_time,
              &metrics->dns_start);
  ConvertTime(dns_end, request_start, request_start_time, &metrics->dns_end);
  ConvertTime(connect_start, request_start, request_start_time,
              &metrics->connect_start);
  ConvertTime(connect_end, request_start, request_start_time,
              &metrics->connect_end);
  ConvertTime(ssl_start, request_start, request_start_time,
              &metrics->ssl_start);
  ConvertTime(ssl_end, request_start, request_start_time, &metrics->ssl_end);
  ConvertTime(send_start, request_start, request_start_time,
              &metrics->sending_start);
  ConvertTime(send_end, request_start, request_start_time,
              &metrics->sending_end);
  ConvertTime(push_start, request_start, request_start_time,
              &metrics->push_start);
  ConvertTime(push_end, request_start, request_start_time, &metrics->push_end);
  ConvertTime(receive_headers_end, request_start, request_start_time,
              &metrics->response_start);
  ConvertTime(request_end, request_start, request_start_time,
              &metrics->request_end);
  metrics->socket_reused = socket_reused;
  metrics->sent_byte_count = sent_bytes_count;
  metrics->received_byte_count = received_bytes_count;
}

void Cronet_UrlRequestImpl::NetworkTasks::OnStatus(
    Cronet_UrlRequestStatusListenerPtr listener,
    net::LoadState load_state) {
  DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_);
  if (final_callback_posted_)
    return;
  {
    base::AutoLock lock(url_request_->lock_);
    auto element = url_request_->status_listeners_.find(listener);
    CHECK(element != url_request_->status_listeners_.end());
    url_request_->status_listeners_.erase(element);
  }

  // Invoke Cronet_UrlRequestCallback_OnCanceled on client executor.
  url_request_->PostTaskToExecutor(
      base::BindOnce(&Cronet_UrlRequestStatusListener_OnStatus, listener,
                     ConvertLoadState(load_state)));
}

}  // namespace cronet

CRONET_EXPORT Cronet_UrlRequestPtr Cronet_UrlRequest_Create() {
  return new cronet::Cronet_UrlRequestImpl();
}
