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

#include "chrome/browser/devtools/devtools_network_transaction.h"

#include "base/profiler/scoped_tracker.h"
#include "chrome/browser/devtools/devtools_network_controller.h"
#include "chrome/browser/devtools/devtools_network_interceptor.h"
#include "net/base/net_errors.h"
#include "net/base/upload_progress.h"
#include "net/http/http_network_transaction.h"
#include "net/http/http_request_info.h"

// Keep in sync with kDevToolsRequestInitiator and
// kDevToolsEmulateNetworkConditionsClientId defined in
// InspectorResourceAgent.cpp.
const char DevToolsNetworkTransaction::kDevToolsRequestInitiator[] =
    "X-DevTools-Request-Initiator";
const char
    DevToolsNetworkTransaction::kDevToolsEmulateNetworkConditionsClientId[] =
        "X-DevTools-Emulate-Network-Conditions-Client-Id";

DevToolsNetworkTransaction::DevToolsNetworkTransaction(
    DevToolsNetworkController* controller,
    scoped_ptr<net::HttpTransaction> network_transaction)
    : controller_(controller),
      network_transaction_(network_transaction.Pass()),
      request_(NULL),
      failed_(false),
      throttled_byte_count_(0),
      callback_type_(NONE),
      proxy_callback_(base::Bind(&DevToolsNetworkTransaction::OnCallback,
                                 base::Unretained(this))) {
  DCHECK(controller);
}

DevToolsNetworkTransaction::~DevToolsNetworkTransaction() {
  if (interceptor_)
    interceptor_->RemoveTransaction(this);
}

void DevToolsNetworkTransaction::Throttle(int result) {
  throttled_result_ = result;

  if (callback_type_ == START)
    throttled_byte_count_ += network_transaction_->GetTotalReceivedBytes();
  if (result > 0)
    throttled_byte_count_ += result;

  if (interceptor_)
    interceptor_->ThrottleTransaction(this, callback_type_ == START);
}

void DevToolsNetworkTransaction::OnCallback(int rv) {
  // TODO(vadimt): Remove ScopedTracker below once crbug.com/424359 is fixed.
  tracked_objects::ScopedTracker tracking_profile(
      FROM_HERE_WITH_EXPLICIT_FUNCTION(
          "424359 DevToolsNetworkTransaction::OnCallback"));

  if (failed_)
    return;
  DCHECK(!callback_.is_null());
  if (callback_type_ == START || callback_type_ == READ) {
    if (interceptor_ && interceptor_->ShouldThrottle(this)) {
      Throttle(rv);
      return;
    }
  }
  net::CompletionCallback callback = callback_;
  callback_.Reset();
  callback_type_ = NONE;
  callback.Run(rv);
}

int DevToolsNetworkTransaction::SetupCallback(
    net::CompletionCallback callback,
    int result,
    CallbackType callback_type) {
  DCHECK(callback_type_ == NONE);

  if (result == net::ERR_IO_PENDING) {
    callback_type_ = callback_type;
    callback_ = callback;
    return result;
  }

  if (!interceptor_ || !interceptor_->ShouldThrottle(this))
    return result;

  // Only START and READ operation throttling is supported.
  if (callback_type != START && callback_type != READ)
    return result;

  // In case of error |throttled_byte_count_| is unknown.
  if (result < 0)
    return result;

  // URLRequestJob relies on synchronous end-of-stream notification.
  if (callback_type == READ && result == 0)
    return result;

  callback_type_ = callback_type;
  callback_ = callback;
  Throttle(result);
  return net::ERR_IO_PENDING;
}

void DevToolsNetworkTransaction::Fail() {
  DCHECK(request_);
  DCHECK(!failed_);
  failed_ = true;
  network_transaction_->SetBeforeNetworkStartCallback(
      BeforeNetworkStartCallback());
  if (callback_.is_null())
    return;
  net::CompletionCallback callback = callback_;
  callback_.Reset();
  callback_type_ = NONE;
  callback.Run(net::ERR_INTERNET_DISCONNECTED);
}

int DevToolsNetworkTransaction::Start(
    const net::HttpRequestInfo* request,
    const net::CompletionCallback& callback,
    const net::BoundNetLog& net_log) {
  DCHECK(request);
  request_ = request;
  interceptor_ = controller_->GetInterceptor(this);
  interceptor_->AddTransaction(this);

  if (interceptor_->ShouldFail(this)) {
    failed_ = true;
    network_transaction_->SetBeforeNetworkStartCallback(
        BeforeNetworkStartCallback());
    return net::ERR_INTERNET_DISCONNECTED;
  }
  int rv = network_transaction_->Start(request_, proxy_callback_, net_log);
  return SetupCallback(callback, rv, START);
}

void DevToolsNetworkTransaction::ProcessRequest() {
  DCHECK(request_);
  bool has_devtools_client_id = request_->extra_headers.HasHeader(
      kDevToolsEmulateNetworkConditionsClientId);
  bool has_devtools_request_initiator = request_->extra_headers.HasHeader(
      kDevToolsRequestInitiator);
  if (!has_devtools_client_id && !has_devtools_request_initiator)
    return;

  custom_request_.reset(new net::HttpRequestInfo(*request_));

  if (has_devtools_client_id) {
    custom_request_->extra_headers.GetHeader(
        kDevToolsEmulateNetworkConditionsClientId, &client_id_);
    custom_request_->extra_headers.RemoveHeader(
        kDevToolsEmulateNetworkConditionsClientId);
  }

  if (has_devtools_request_initiator) {
    custom_request_->extra_headers.GetHeader(
        kDevToolsRequestInitiator, &request_initiator_);
    custom_request_->extra_headers.RemoveHeader(kDevToolsRequestInitiator);
  }

  request_ = custom_request_.get();
}

int DevToolsNetworkTransaction::RestartIgnoringLastError(
    const net::CompletionCallback& callback) {
  if (failed_)
    return net::ERR_INTERNET_DISCONNECTED;
  int rv = network_transaction_->RestartIgnoringLastError(proxy_callback_);
  return SetupCallback(callback, rv, RESTART_IGNORING_LAST_ERROR);
}

int DevToolsNetworkTransaction::RestartWithCertificate(
    net::X509Certificate* client_cert,
    const net::CompletionCallback& callback) {
  if (failed_)
    return net::ERR_INTERNET_DISCONNECTED;
  int rv = network_transaction_->RestartWithCertificate(
      client_cert, proxy_callback_);
  return SetupCallback(callback, rv, RESTART_WITH_CERTIFICATE);
}

int DevToolsNetworkTransaction::RestartWithAuth(
    const net::AuthCredentials& credentials,
    const net::CompletionCallback& callback) {
  if (failed_)
    return net::ERR_INTERNET_DISCONNECTED;
  int rv = network_transaction_->RestartWithAuth(credentials, proxy_callback_);
  return SetupCallback(callback, rv, RESTART_WITH_AUTH);
}

bool DevToolsNetworkTransaction::IsReadyToRestartForAuth() {
  return network_transaction_->IsReadyToRestartForAuth();
}

int DevToolsNetworkTransaction::Read(
    net::IOBuffer* buf,
    int buf_len,
    const net::CompletionCallback& callback) {
  if (failed_)
    return net::ERR_INTERNET_DISCONNECTED;
  int rv = network_transaction_->Read(buf, buf_len, proxy_callback_);
  return SetupCallback(callback, rv, READ);
}

void DevToolsNetworkTransaction::StopCaching() {
  network_transaction_->StopCaching();
}

bool DevToolsNetworkTransaction::GetFullRequestHeaders(
    net::HttpRequestHeaders* headers) const {
  return network_transaction_->GetFullRequestHeaders(headers);
}

int64 DevToolsNetworkTransaction::GetTotalReceivedBytes() const {
  return network_transaction_->GetTotalReceivedBytes();
}

void DevToolsNetworkTransaction::DoneReading() {
  network_transaction_->DoneReading();
}

const net::HttpResponseInfo*
DevToolsNetworkTransaction::GetResponseInfo() const {
  return network_transaction_->GetResponseInfo();
}

net::LoadState DevToolsNetworkTransaction::GetLoadState() const {
  return network_transaction_->GetLoadState();
}

net::UploadProgress DevToolsNetworkTransaction::GetUploadProgress() const {
  return network_transaction_->GetUploadProgress();
}

void DevToolsNetworkTransaction::SetQuicServerInfo(
    net::QuicServerInfo* quic_server_info) {
  network_transaction_->SetQuicServerInfo(quic_server_info);
}

bool DevToolsNetworkTransaction::GetLoadTimingInfo(
    net::LoadTimingInfo* load_timing_info) const {
  return network_transaction_->GetLoadTimingInfo(load_timing_info);
}

void DevToolsNetworkTransaction::SetPriority(net::RequestPriority priority) {
  network_transaction_->SetPriority(priority);
}

void DevToolsNetworkTransaction::SetWebSocketHandshakeStreamCreateHelper(
    net::WebSocketHandshakeStreamBase::CreateHelper* create_helper) {
  network_transaction_->SetWebSocketHandshakeStreamCreateHelper(create_helper);
}

void DevToolsNetworkTransaction::SetBeforeNetworkStartCallback(
    const BeforeNetworkStartCallback& callback) {
  network_transaction_->SetBeforeNetworkStartCallback(callback);
}

void DevToolsNetworkTransaction::SetBeforeProxyHeadersSentCallback(
    const BeforeProxyHeadersSentCallback& callback) {
  network_transaction_->SetBeforeProxyHeadersSentCallback(callback);
}

int DevToolsNetworkTransaction::ResumeNetworkStart() {
  if (failed_)
    return net::ERR_INTERNET_DISCONNECTED;
  return network_transaction_->ResumeNetworkStart();
}

void DevToolsNetworkTransaction::FireThrottledCallback() {
  DCHECK(!callback_.is_null());
  DCHECK(callback_type_ == READ || callback_type_ == START);
  net::CompletionCallback callback = callback_;
  callback_.Reset();
  callback_type_ = NONE;
  callback.Run(throttled_result_);
}
