// 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::kUmaTargetedHistogramFlag);
  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,
                        net::DEFAULT_PRIORITY,
                        &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;
  }

  scoped_ptr<net::DatagramClientSocket> udp_socket =
      socket_factory_->CreateDatagramClientSocket(
          net::DatagramSocket::DEFAULT_BIND,
          net::RandIntCallback(),
          NULL,
          net::NetLog::Source());
  DCHECK(udp_socket);
  DCHECK(!socket_);
  socket_ = udp_socket.Pass();

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

  socket_->SetSendBufferSize(kMaxUdpSendBufferSize);
  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() reads data for all HelloReply and all subsequent probe tests.
    if (ReadData() != net::ERR_IO_PENDING)
      return false;
    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);

  int result = SendData(output);
  if (result < 0 && result != net::ERR_IO_PENDING)
    TestPhaseComplete(WRITE_FAILED, result);
}

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();
  int result = SendData(output);
  if (result < 0 && result != net::ERR_IO_PENDING)
    TestPhaseComplete(WRITE_FAILED, result);
}

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

  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));
  return 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(base::IgnoreResult(&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) {
    // All packets have not been received for the current test.
    return false;
  }
  // All packets are received for the current test.
  // Read completes if all tests are done.
  bool all_tests_done = current_test_index_ >= maximum_tests_ ||
      current_test_index_ + 1 >= test_sequence_.size();
  TestPhaseComplete(SUCCESS, net::OK);
  return all_tests_done;
}

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;
}

int NetworkStats::SendData(const std::string& output) {
  if (write_buffer_.get() || !socket_.get())
    return net::ERR_UNEXPECTED;
  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, weak_factory_.GetWeakPtr()));
  if (bytes_written < 0)
    return bytes_written;
  UpdateSendBuffer(bytes_written);
  return net::OK;
}

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_;
  delete 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%d.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%d.", 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%d.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%d.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) {
  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 = kDivisor / 200;

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

    // 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, base::FieldTrial::SESSION_RANDOMIZED, 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
