// Copyright 2012 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/net/network_stats.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/rand_util.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "chrome/common/chrome_version_info.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/net_errors.h"
#include "net/base/network_change_notifier.h"
#include "net/base/test_completion_callback.h"
#include "net/dns/single_request_host_resolver.h"
#include "net/proxy/proxy_service.h"
#include "net/socket/client_socket_factory.h"
#include "net/udp/datagram_client_socket.h"
#include "url/gurl.h"

using content::BrowserThread;

namespace chrome_browser_net {

// static
uint32 NetworkStats::maximum_tests_ = 6;
// static
uint32 NetworkStats::maximum_sequential_packets_ = 21;
// static
uint32 NetworkStats::maximum_NAT_packets_ = 2;
// static
uint32 NetworkStats::maximum_NAT_idle_seconds_ = 300;
// static
bool NetworkStats::start_test_after_connect_ = true;

// Specify the possible choices of probe packet sizes.
const uint32 kProbePacketBytes[] = {100, 500, 1200};
const uint32 kPacketSizeChoices = arraysize(kProbePacketBytes);

// List of ports used for probing test.
const uint16 kPorts[] = {443, 80};

// Number of first few packets that are recorded in a packet-correlation
// histogram, which shows exactly what sequence of packets were received.
// We use this to deduce specific packet loss correlation.
const uint32 kCorrelatedLossPacketCount = 6;

// This specifies the maximum message (payload) size of one packet.
const uint32 kMaxMessageSize = 1300;

// This specifies the maximum udp receiver buffer size.
const uint32 kMaxUdpReceiveBufferSize = 63000;

// This specifies the maximum udp receiver buffer size.
const uint32 kMaxUdpSendBufferSize = 4096;

// This should match TestType except for the last one.
const char* kTestName[] = {"TokenRequest", "StartPacket", "NonPacedPacket",
                           "PacedPacket", "NATBind"};

// Perform Pacing/Non-pacing test only if at least 2 packets are received
// in the StartPacketTest.
const uint32 kMinimumReceivedPacketsForPacingTest = 2;
// Perform NAT binding test only if at least 10 packets are received.
const uint32 kMinimumReceivedPacketsForNATTest = 10;

// Maximum inter-packet pacing interval in microseconds.
const uint32 kMaximumPacingMicros = 1000000;
// Timeout value for getting the token.
const uint32 kGetTokenTimeoutSeconds = 10;
// Timeout value for StartPacket and NonPacedPacket if the client does not get
// reply. For PacedPacket test, the timeout value is this number plus the total
// pacing interval.
const uint32 kReadDataTimeoutSeconds = 30;
// This is the timeout for NAT without Idle periods.
// For NAT test with idle periods, the timeout is the Idle period + this value.
const uint32 kReadNATTimeoutSeconds = 10;

// These helper functions are similar to UMA_HISTOGRAM_XXX except that they do
// not create a static histogram_pointer.
void DynamicHistogramEnumeration(const std::string& name,
                                 uint32 sample,
                                 uint32 boundary_value) {
  base::HistogramBase* histogram_pointer = base::LinearHistogram::FactoryGet(
      name,
      1,
      boundary_value,
      boundary_value + 1,
      base::HistogramBase::kUmaTargetedHistogramFlag);
  histogram_pointer->Add(sample);
}

void DynamicHistogramTimes(const std::string& name,
                           const base::TimeDelta& sample) {
  base::HistogramBase* histogram_pointer = base::Histogram::FactoryTimeGet(
      name,
      base::TimeDelta::FromMilliseconds(1),
      base::TimeDelta::FromSeconds(30),
      50,
      base::HistogramBase::kUmaTargetedHistogramFlag);
  histogram_pointer->AddTime(sample);
}

void DynamicHistogramCounts(const std::string& name,
                            uint32 sample,
                            uint32 min,
                            uint32 max,
                            uint32 bucket_count) {
  base::HistogramBase* histogram_pointer = base::Histogram::FactoryGet(
      name, min, max, bucket_count, base::HistogramBase::kNoFlags);
  histogram_pointer->Add(sample);
}

NetworkStats::NetworkStats(net::ClientSocketFactory* socket_factory)
    : socket_factory_(socket_factory),
      histogram_port_(0),
      has_proxy_server_(false),
      probe_packet_bytes_(0),
      current_test_index_(0),
      weak_factory_(this) {
  ResetData();
}

NetworkStats::~NetworkStats() {}

bool NetworkStats::Start(net::HostResolver* host_resolver,
                         const net::HostPortPair& server_host_port_pair,
                         uint16 histogram_port,
                         bool has_proxy_server,
                         uint32 probe_bytes,
                         const net::CompletionCallback& finished_callback) {
  DCHECK(host_resolver);
  histogram_port_ = histogram_port;
  has_proxy_server_ = has_proxy_server;
  probe_packet_bytes_ = probe_bytes;
  finished_callback_ = finished_callback;
  test_sequence_.clear();
  test_sequence_.push_back(TOKEN_REQUEST);

  ResetData();

  scoped_ptr<net::SingleRequestHostResolver> resolver(
      new net::SingleRequestHostResolver(host_resolver));
  net::HostResolver::RequestInfo request(server_host_port_pair);
  int rv =
      resolver->Resolve(request,
                        &addresses_,
                        base::Bind(base::IgnoreResult(&NetworkStats::DoConnect),
                                   base::Unretained(this)),
                        net::BoundNetLog());
  if (rv == net::ERR_IO_PENDING) {
    resolver_.swap(resolver);
    return true;
  }
  return DoConnect(rv);
}

void NetworkStats::StartOneTest() {
  if (test_sequence_[current_test_index_] == TOKEN_REQUEST) {
    write_buffer_ = NULL;
    SendHelloRequest();
  } else {
    SendProbeRequest();
  }
}

void NetworkStats::ResetData() {
  write_buffer_ = NULL;
  packets_received_mask_.reset();
  first_arrival_time_ = base::TimeTicks();
  last_arrival_time_ = base::TimeTicks();

  packet_rtt_.clear();
  packet_rtt_.resize(maximum_sequential_packets_);
  probe_request_time_ = base::TimeTicks();
  // Note: inter_arrival_time_ should not be reset here because it is used in
  // subsequent tests.
}

bool NetworkStats::DoConnect(int result) {
  if (result != net::OK) {
    TestPhaseComplete(RESOLVE_FAILED, result);
    return false;
  }

  net::DatagramClientSocket* udp_socket =
      socket_factory_->CreateDatagramClientSocket(
          net::DatagramSocket::DEFAULT_BIND,
          net::RandIntCallback(),
          NULL,
          net::NetLog::Source());
  if (!udp_socket) {
    TestPhaseComplete(SOCKET_CREATE_FAILED, net::ERR_INVALID_ARGUMENT);
    return false;
  }
  DCHECK(!socket_.get());
  socket_.reset(udp_socket);

  const net::IPEndPoint& endpoint = addresses_.front();
  int rv = udp_socket->Connect(endpoint);
  if (rv < 0) {
    TestPhaseComplete(CONNECT_FAILED, rv);
    return false;
  }

  udp_socket->SetSendBufferSize(kMaxUdpSendBufferSize);
  udp_socket->SetReceiveBufferSize(kMaxUdpReceiveBufferSize);
  return ConnectComplete(rv);
}

bool NetworkStats::ConnectComplete(int result) {
  if (result < 0) {
    TestPhaseComplete(CONNECT_FAILED, result);
    return false;
  }

  if (start_test_after_connect_) {
    ReadData();  // This ReadData() reads data for all HelloReply and all
                 // subsequent probe tests.
    SendHelloRequest();
  } else {
    // For unittesting. Only run the callback, do not destroy it.
    if (!finished_callback_.is_null())
      finished_callback_.Run(result);
  }
  return true;
}

void NetworkStats::SendHelloRequest() {
  StartReadDataTimer(kGetTokenTimeoutSeconds, current_test_index_);
  ProbePacket probe_packet;
  probe_message_.SetPacketHeader(ProbePacket_Type_HELLO_REQUEST, &probe_packet);
  probe_packet.set_group_id(current_test_index_);
  std::string output = probe_message_.MakeEncodedPacket(probe_packet);

  SendData(output);
}

void NetworkStats::SendProbeRequest() {
  ResetData();
  // Use default timeout except for the NAT bind test.
  uint32 timeout_seconds = kReadDataTimeoutSeconds;
  uint32 number_packets = maximum_sequential_packets_;
  pacing_interval_ = base::TimeDelta();
  switch (test_sequence_[current_test_index_]) {
    case START_PACKET_TEST:
    case NON_PACED_PACKET_TEST:
      break;
    case PACED_PACKET_TEST: {
      pacing_interval_ =
          std::min(inter_arrival_time_,
                   base::TimeDelta::FromMicroseconds(kMaximumPacingMicros));
      timeout_seconds += pacing_interval_.InMicroseconds() *
                         (maximum_sequential_packets_ - 1) / 1000000;
      break;
    }
    case NAT_BIND_TEST: {
      // Make sure no integer overflow.
      DCHECK_LE(maximum_NAT_idle_seconds_, 4000U);
      int nat_test_idle_seconds = base::RandInt(1, maximum_NAT_idle_seconds_);
      pacing_interval_ = base::TimeDelta::FromSeconds(nat_test_idle_seconds);
      timeout_seconds = nat_test_idle_seconds + kReadNATTimeoutSeconds;
      number_packets = maximum_NAT_packets_;
      break;
    }
    default:
      NOTREACHED();
      return;
  }
  DVLOG(1) << "NetworkStat: Probe pacing " << pacing_interval_.InMicroseconds()
           << " microseconds. Time out " << timeout_seconds << " seconds";
  ProbePacket probe_packet;
  probe_message_.GenerateProbeRequest(token_,
                                      current_test_index_,
                                      probe_packet_bytes_,
                                      pacing_interval_.InMicroseconds(),
                                      number_packets,
                                      &probe_packet);
  std::string output = probe_message_.MakeEncodedPacket(probe_packet);

  StartReadDataTimer(timeout_seconds, current_test_index_);
  probe_request_time_ = base::TimeTicks::Now();
  SendData(output);
}

void NetworkStats::ReadData() {
  if (!socket_.get())
    return;

  int rv = 0;
  do {
    DCHECK(!read_buffer_.get());
    read_buffer_ = new net::IOBuffer(kMaxMessageSize);

    rv = socket_->Read(
        read_buffer_.get(),
        kMaxMessageSize,
        base::Bind(&NetworkStats::OnReadComplete, base::Unretained(this)));
  } while (rv > 0 && !ReadComplete(rv));
}

void NetworkStats::OnReadComplete(int result) {
  if (!ReadComplete(result)) {
    // Called ReadData() via PostDelayedTask() to avoid recursion. Added a delay
    // of 1ms so that the time-out will fire before we have time to really hog
    // the CPU too extensively (waiting for the time-out) in case of an infinite
    // loop.
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&NetworkStats::ReadData, weak_factory_.GetWeakPtr()),
        base::TimeDelta::FromMilliseconds(1));
  }
}

bool NetworkStats::ReadComplete(int result) {
  DCHECK(socket_.get());
  DCHECK_NE(net::ERR_IO_PENDING, result);
  if (result < 0) {
    // Something is wrong, finish the test.
    read_buffer_ = NULL;
    TestPhaseComplete(READ_FAILED, result);
    return true;
  }

  std::string encoded_message(read_buffer_->data(),
                              read_buffer_->data() + result);
  read_buffer_ = NULL;
  ProbePacket probe_packet;
  if (!probe_message_.ParseInput(encoded_message, &probe_packet))
    return false;
  // Discard if the packet is for a different test.
  if (probe_packet.group_id() != current_test_index_)
    return false;

  // Whether all packets in the current test have been received.
  bool current_test_complete = false;
  switch (probe_packet.header().type()) {
    case ProbePacket_Type_HELLO_REPLY:
      token_ = probe_packet.token();
      if (current_test_index_ == 0)
        test_sequence_.push_back(START_PACKET_TEST);
      current_test_complete = true;
      break;
    case ProbePacket_Type_PROBE_REPLY:
      current_test_complete = UpdateReception(probe_packet);
      break;
    default:
      DVLOG(1) << "Received unexpected packet type: "
               << probe_packet.header().type();
  }

  if (current_test_complete) {
    TestPhaseComplete(SUCCESS, net::OK);
    // Read only completes if all tests are done.
    // current_test_index_ is incremented in TestPhaseComplete().
    return current_test_index_ >= test_sequence_.size();
  }
  // All packets have not been received.
  return false;
}

bool NetworkStats::UpdateReception(const ProbePacket& probe_packet) {
  uint32 packet_index = probe_packet.packet_index();
  if (packet_index >= packet_rtt_.size())
    return false;
  packets_received_mask_.set(packet_index);
  TestType test_type = test_sequence_[current_test_index_];
  uint32 received_packets = packets_received_mask_.count();

  // Now() has resolution ~1-15ms. HighResNow() has high resolution but it
  // is warned not to use it unless necessary.
  base::TimeTicks current_time = base::TimeTicks::Now();
  last_arrival_time_ = current_time;
  if (first_arrival_time_.is_null())
    first_arrival_time_ = current_time;

  // Need to do this after updating the last_arrival_time_ since NAT_BIND_TEST
  // records the SendToLastRecvDelay.
  if (test_type == NAT_BIND_TEST) {
    return received_packets >= maximum_NAT_packets_;
  }

  base::TimeDelta rtt =
      current_time - probe_request_time_ -
      base::TimeDelta::FromMicroseconds(std::max(
          static_cast<int64>(0), probe_packet.server_processing_micros()));
  base::TimeDelta min_rtt = base::TimeDelta::FromMicroseconds(1L);
  packet_rtt_[packet_index] = (rtt >= min_rtt) ? rtt : min_rtt;

  if (received_packets < maximum_sequential_packets_)
    return false;
  // All packets in the current test are received.
  inter_arrival_time_ = (last_arrival_time_ - first_arrival_time_) /
      std::max(1U, (received_packets - 1));
  if (test_type == START_PACKET_TEST) {
    // No need to add TOKEN_REQUEST here when all packets are received.
    test_sequence_.push_back(base::RandInt(0, 1) ? PACED_PACKET_TEST
                                                 : NON_PACED_PACKET_TEST);
    test_sequence_.push_back(TOKEN_REQUEST);
    test_sequence_.push_back(NAT_BIND_TEST);
    test_sequence_.push_back(TOKEN_REQUEST);
  }
  return true;
}

void NetworkStats::SendData(const std::string& output) {
  DCHECK(!write_buffer_.get());
  scoped_refptr<net::StringIOBuffer> buffer(new net::StringIOBuffer(output));
  write_buffer_ = new net::DrainableIOBuffer(buffer.get(), buffer->size());

  int bytes_written = socket_->Write(
      write_buffer_.get(),
      write_buffer_->BytesRemaining(),
      base::Bind(&NetworkStats::OnWriteComplete, base::Unretained(this)));
  if (bytes_written < 0) {
    if (bytes_written != net::ERR_IO_PENDING)
      // There is some unexpected error.
      TestPhaseComplete(WRITE_FAILED, bytes_written);
  } else {
    UpdateSendBuffer(bytes_written);
  }
}

void NetworkStats::OnWriteComplete(int result) {
  DCHECK(socket_.get());
  DCHECK_NE(net::ERR_IO_PENDING, result);
  if (result < 0) {
    TestPhaseComplete(WRITE_FAILED, result);
    return;
  }
  UpdateSendBuffer(result);
}

void NetworkStats::UpdateSendBuffer(int bytes_sent) {
  write_buffer_->DidConsume(bytes_sent);
  DCHECK_EQ(write_buffer_->BytesRemaining(), 0);
  write_buffer_ = NULL;
}

void NetworkStats::StartReadDataTimer(uint32 seconds, uint32 test_index) {
  base::MessageLoop::current()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&NetworkStats::OnReadDataTimeout,
                 weak_factory_.GetWeakPtr(),
                 test_index),
      base::TimeDelta::FromSeconds(seconds));
}

void NetworkStats::OnReadDataTimeout(uint32 test_index) {
  // If the current_test_index_ has changed since we set the timeout,
  // the current test has been completed, so do nothing.
  if (test_index != current_test_index_)
    return;
  // If test_type is TOKEN_REQUEST, it will do nothing but call
  // TestPhaseComplete().
  TestType test_type = test_sequence_[current_test_index_];

  uint32 received_packets = packets_received_mask_.count();
  if (received_packets >= 2) {
    inter_arrival_time_ =
        (last_arrival_time_ - first_arrival_time_) / (received_packets - 1);
  }
  // Add other tests if this is START_PACKET_TEST.
  if (test_type == START_PACKET_TEST) {
    if (received_packets >= kMinimumReceivedPacketsForPacingTest) {
      test_sequence_.push_back(TOKEN_REQUEST);
      test_sequence_.push_back(base::RandInt(0, 1) ? PACED_PACKET_TEST
                                                   : NON_PACED_PACKET_TEST);
    }
    if (received_packets >= kMinimumReceivedPacketsForNATTest) {
      test_sequence_.push_back(TOKEN_REQUEST);
      test_sequence_.push_back(NAT_BIND_TEST);
      test_sequence_.push_back(TOKEN_REQUEST);
    }
  }
  TestPhaseComplete(READ_TIMED_OUT, net::ERR_FAILED);
}

void NetworkStats::TestPhaseComplete(Status status, int result) {
  // If there is no valid token, do nothing and delete self.
  // This includes all connection error, name resolve error, etc.
  if (token_.timestamp_micros() != 0) {
    TestType current_test = test_sequence_[current_test_index_];
    DCHECK_LT(current_test, TEST_TYPE_MAX);
    if (current_test != TOKEN_REQUEST)
      RecordHistograms(current_test);
    else if (current_test_index_ > 0 &&
             test_sequence_[current_test_index_ - 1] == NAT_BIND_TEST) {
      // We record the NATTestReceivedHistograms after the succeeding
      // TokenRequest.
      RecordNATTestReceivedHistograms(status);
    }

    // Move to the next test.
    current_test = GetNextTest();
    if (current_test_index_ <= maximum_tests_ && current_test < TEST_TYPE_MAX) {
      DVLOG(1) << "NetworkStat: Start Probe test: " << current_test;
      base::MessageLoop::current()->PostTask(
          FROM_HERE,
          base::Bind(&NetworkStats::StartOneTest, weak_factory_.GetWeakPtr()));
      return;
    }
  }

  // All tests are done.
  DoFinishCallback(result);

  // Close the socket so that there are no more IO operations.
  if (socket_.get())
    socket_->Close();

  DVLOG(1) << "NetworkStat: schedule delete self at test index "
           << current_test_index_;
  base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}

NetworkStats::TestType NetworkStats::GetNextTest() {
  ++current_test_index_;
  if (current_test_index_ >= test_sequence_.size())
    return TEST_TYPE_MAX;
  return test_sequence_[current_test_index_];
}

void NetworkStats::DoFinishCallback(int result) {
  if (!finished_callback_.is_null()) {
    net::CompletionCallback callback = finished_callback_;
    finished_callback_.Reset();
    callback.Run(result);
  }
}

void NetworkStats::RecordHistograms(TestType test_type) {
  switch (test_type) {
    case START_PACKET_TEST:
    case NON_PACED_PACKET_TEST:
    case PACED_PACKET_TEST: {
      RecordInterArrivalHistograms(test_type);
      RecordPacketLossSeriesHistograms(test_type);
      RecordPacketsReceivedHistograms(test_type);
      // Only record RTT for these packet indices.
      uint32 rtt_indices[] = {0, 1, 2, 9, 19};
      for (uint32 i = 0; i < arraysize(rtt_indices); ++i) {
        if (rtt_indices[i] < packet_rtt_.size())
          RecordRTTHistograms(test_type, rtt_indices[i]);
      }
      RecordSendToLastRecvDelayHistograms(test_type);
      return;
    }
    case NAT_BIND_TEST:
      RecordSendToLastRecvDelayHistograms(test_type);
      return;
    default:
      DVLOG(1) << "Unexpected test type " << test_type
               << " in RecordHistograms.";
  }
}

void NetworkStats::RecordInterArrivalHistograms(TestType test_type) {
  std::string histogram_name =
      base::StringPrintf("NetConnectivity4.%s.Sent%02d.PacketDelay.%d.%dB",
                         kTestName[test_type],
                         maximum_sequential_packets_,
                         histogram_port_,
                         probe_packet_bytes_);
  // Record the time normalized to 20 packet inter-arrivals.
  DynamicHistogramTimes(histogram_name, inter_arrival_time_ * 20);
}

void NetworkStats::RecordPacketsReceivedHistograms(TestType test_type) {
  const char* test_name = kTestName[test_type];
  std::string histogram_prefix = base::StringPrintf(
      "NetConnectivity4.%s.Sent%02d.", test_name, maximum_sequential_packets_);
  std::string histogram_suffix =
      base::StringPrintf(".%d.%dB", histogram_port_, probe_packet_bytes_);
  std::string name = histogram_prefix + "GotAPacket" + histogram_suffix;
  base::HistogramBase* histogram_pointer = base::BooleanHistogram::FactoryGet(
      name, base::HistogramBase::kUmaTargetedHistogramFlag);
  histogram_pointer->Add(packets_received_mask_.any());

  DynamicHistogramEnumeration(
      histogram_prefix + "PacketsRecv" + histogram_suffix,
      packets_received_mask_.count(),
      maximum_sequential_packets_ + 1);

  if (!packets_received_mask_.any())
    return;

  base::HistogramBase* received_nth_packet_histogram =
      base::Histogram::FactoryGet(
          histogram_prefix + "RecvNthPacket" + histogram_suffix,
          1,
          maximum_sequential_packets_ + 1,
          maximum_sequential_packets_ + 2,
          base::HistogramBase::kUmaTargetedHistogramFlag);

  int count = 0;
  for (size_t j = 0; j < maximum_sequential_packets_; ++j) {
    int packet_number = j + 1;
    if (packets_received_mask_.test(j)) {
      received_nth_packet_histogram->Add(packet_number);
      ++count;
    }
    std::string histogram_name =
        base::StringPrintf("%sNumRecvFromFirst%02dPackets%s",
                           histogram_prefix.c_str(),
                           packet_number,
                           histogram_suffix.c_str());
    DynamicHistogramEnumeration(histogram_name, count, packet_number + 1);
  }
}

void NetworkStats::RecordNATTestReceivedHistograms(Status status) {
  const char* test_name = kTestName[NAT_BIND_TEST];
  bool test_result = status == SUCCESS;
  std::string middle_name = test_result ? "Connectivity.Success"
                                        : "Connectivity.Failure";
  // Record whether the HelloRequest got reply successfully.
  std::string histogram_name =
      base::StringPrintf("NetConnectivity4.%s.Sent%d.%s.%d.%dB",
                         test_name,
                         maximum_NAT_packets_,
                         middle_name.c_str(),
                         histogram_port_,
                         probe_packet_bytes_);
  uint32 bucket_count = std::min(maximum_NAT_idle_seconds_ + 2, 50U);
  DynamicHistogramCounts(histogram_name,
                         pacing_interval_.InSeconds(),
                         1,
                         maximum_NAT_idle_seconds_ + 1,
                         bucket_count);

  // Record the NAT bind result only if the HelloRequest successfully got the
  // token and the first NAT test packet is received.
  if (!test_result || !packets_received_mask_.test(0))
    return;

  middle_name = packets_received_mask_.test(1) ? "Bind.Success"
                                               : "Bind.Failure";
  histogram_name = base::StringPrintf("NetConnectivity4.%s.Sent%d.%s.%d.%dB",
                                      test_name,
                                      maximum_NAT_packets_,
                                      middle_name.c_str(),
                                      histogram_port_,
                                      probe_packet_bytes_);
  DynamicHistogramCounts(histogram_name,
                         pacing_interval_.InSeconds(),
                         1,
                         maximum_NAT_idle_seconds_ + 1,
                         bucket_count);
}

void NetworkStats::RecordPacketLossSeriesHistograms(TestType test_type) {
  const char* test_name = kTestName[test_type];
  // Build "NetConnectivity4.<TestName>.First6.SeriesRecv.<port>.<probe_size>"
  // histogram name. Total 3(tests) x 12 histograms.
  std::string series_acked_histogram_name =
      base::StringPrintf("NetConnectivity4.%s.First6.SeriesRecv.%d.%dB",
                         test_name,
                         histogram_port_,
                         probe_packet_bytes_);
  uint32 histogram_boundary = 1 << kCorrelatedLossPacketCount;
  uint32 correlated_packet_mask =
      (histogram_boundary - 1) & packets_received_mask_.to_ulong();
  DynamicHistogramEnumeration(
      series_acked_histogram_name, correlated_packet_mask, histogram_boundary);

  // If we are running without a proxy, we'll generate an extra histogram with
  // the ".NoProxy" suffix.
  if (!has_proxy_server_) {
    series_acked_histogram_name.append(".NoProxy");
    DynamicHistogramEnumeration(series_acked_histogram_name,
                                correlated_packet_mask,
                                histogram_boundary);
  }
}

void NetworkStats::RecordRTTHistograms(TestType test_type, uint32 index) {
  DCHECK_LT(index, packet_rtt_.size());

  if (!packets_received_mask_.test(index))
    return;  // Probe packet never received.

  std::string rtt_histogram_name = base::StringPrintf(
      "NetConnectivity4.%s.Sent%02d.Success.RTT.Packet%02d.%d.%dB",
      kTestName[test_type],
      maximum_sequential_packets_,
      index + 1,
      histogram_port_,
      probe_packet_bytes_);
  DynamicHistogramTimes(rtt_histogram_name, packet_rtt_[index]);
}

void NetworkStats::RecordSendToLastRecvDelayHistograms(TestType test_type) {
  if (packets_received_mask_.count() < 2)
    return;  // Too few packets are received.
  uint32 packets_sent = test_type == NAT_BIND_TEST
      ? maximum_NAT_packets_ : maximum_sequential_packets_;
  std::string histogram_name = base::StringPrintf(
      "NetConnectivity4.%s.Sent%02d.SendToLastRecvDelay.%d.%dB",
      kTestName[test_type],
      packets_sent,
      histogram_port_,
      probe_packet_bytes_);
  base::TimeDelta send_to_last_recv_time =
      std::max(last_arrival_time_ - probe_request_time_ -
                   pacing_interval_ * (packets_sent - 1),
               base::TimeDelta::FromMilliseconds(0));
  DynamicHistogramTimes(histogram_name, send_to_last_recv_time);
}

// ProxyDetector methods and members.
ProxyDetector::ProxyDetector(net::ProxyService* proxy_service,
                             const net::HostPortPair& server_address,
                             OnResolvedCallback callback)
    : proxy_service_(proxy_service),
      server_address_(server_address),
      callback_(callback),
      has_pending_proxy_resolution_(false) {}

ProxyDetector::~ProxyDetector() {
  CHECK(!has_pending_proxy_resolution_);
}

void ProxyDetector::StartResolveProxy() {
  std::string url =
      base::StringPrintf("https://%s", server_address_.ToString().c_str());
  GURL gurl(url);

  has_pending_proxy_resolution_ = true;
  DCHECK(proxy_service_);
  int rv = proxy_service_->ResolveProxy(
      gurl,
      &proxy_info_,
      base::Bind(&ProxyDetector::OnResolveProxyComplete,
                 base::Unretained(this)),
      NULL,
      net::BoundNetLog());
  if (rv != net::ERR_IO_PENDING)
    OnResolveProxyComplete(rv);
}

void ProxyDetector::OnResolveProxyComplete(int result) {
  has_pending_proxy_resolution_ = false;
  bool has_proxy_server =
      (result == net::OK && proxy_info_.proxy_server().is_valid() &&
       !proxy_info_.proxy_server().is_direct());

  OnResolvedCallback callback = callback_;
  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE, base::Bind(callback, has_proxy_server));

  // TODO(rtenneti): Will we leak if ProxyResolve is cancelled (or proxy
  // resolution never completes).
  delete this;
}

void CollectNetworkStats(const std::string& network_stats_server,
                         IOThread* io_thread) {
  // TODO(honghaiz): The echotest is temporarily stopped and will be replaced
  // with a new test.
  return;
  // Below is the original code.
  if (network_stats_server.empty())
    return;

  // If we are not on IO Thread, then post a task to call CollectNetworkStats on
  // IO Thread.
  if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
    BrowserThread::PostTask(
        BrowserThread::IO,
        FROM_HERE,
        base::Bind(&CollectNetworkStats, network_stats_server, io_thread));
    return;
  }

  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));

  // Check that there is a network connection. We get called only if UMA upload
  // to the server has succeeded.
  DCHECK(!net::NetworkChangeNotifier::IsOffline());

  CR_DEFINE_STATIC_LOCAL(scoped_refptr<base::FieldTrial>, trial, ());
  static bool collect_stats = false;

  if (!trial.get()) {
    // Set up a field trial to collect network stats for UDP.
    const base::FieldTrial::Probability kDivisor = 1000;

    // Enable the connectivity testing for 0.5% of the users in stable channel.
    base::FieldTrial::Probability probability_per_group = 5;

    chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
    if (channel == chrome::VersionInfo::CHANNEL_CANARY)
      probability_per_group = kDivisor;
    else if (channel == chrome::VersionInfo::CHANNEL_DEV)
      // Enable the connectivity testing for 50% of the users in dev channel.
      probability_per_group = 500;
    else if (channel == chrome::VersionInfo::CHANNEL_BETA)
      // Enable the connectivity testing for 5% of the users in beta channel.
      probability_per_group = 50;

    // After July 31, 2014 builds, it will always be in default group
    // (disable_network_stats).
    trial = base::FieldTrialList::FactoryGetFieldTrial("NetworkConnectivity",
                                                       kDivisor,
                                                       "disable_network_stats",
                                                       2014,
                                                       7,
                                                       31,
                                                       NULL);

    // Add option to collect_stats for NetworkConnectivity.
    int collect_stats_group =
        trial->AppendGroup("collect_stats", probability_per_group);
    if (trial->group() == collect_stats_group)
      collect_stats = true;
  }

  if (!collect_stats)
    return;

  // Run test kMaxNumberOfTests times.
  const size_t kMaxNumberOfTests = INT_MAX;
  static size_t number_of_tests_done = 0;
  if (number_of_tests_done > kMaxNumberOfTests)
    return;
  ++number_of_tests_done;

  net::HostResolver* host_resolver = io_thread->globals()->host_resolver.get();
  DCHECK(host_resolver);

  uint32 port_index = base::RandInt(0, arraysize(kPorts) - 1);
  uint16 histogram_port = kPorts[port_index];
  net::HostPortPair server_address(network_stats_server, histogram_port);

  net::ProxyService* proxy_service =
      io_thread->globals()->system_proxy_service.get();
  DCHECK(proxy_service);

  ProxyDetector::OnResolvedCallback callback = base::Bind(
      &StartNetworkStatsTest, host_resolver, server_address, histogram_port);

  ProxyDetector* proxy_client =
      new ProxyDetector(proxy_service, server_address, callback);
  proxy_client->StartResolveProxy();
}

void StartNetworkStatsTest(net::HostResolver* host_resolver,
                           const net::HostPortPair& server_address,
                           uint16 histogram_port,
                           bool has_proxy_server) {
  int probe_choice = base::RandInt(0, kPacketSizeChoices - 1);

  // |udp_stats_client| is owned and deleted in the class NetworkStats.
  NetworkStats* udp_stats_client =
      new NetworkStats(net::ClientSocketFactory::GetDefaultFactory());
  udp_stats_client->Start(host_resolver,
                          server_address,
                          histogram_port,
                          has_proxy_server,
                          kProbePacketBytes[probe_choice],
                          net::CompletionCallback());
}

}  // namespace chrome_browser_net
