// Copyright (c) 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 "net/base/network_activity_monitor.h"

#include <vector>

#include "base/bind.h"
#include "base/port.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace test {

class NetworkActivityMonitorPeer {
 public:
  static void ResetMonitor() {
    NetworkActivityMonitor* monitor = NetworkActivityMonitor::GetInstance();
    base::AutoLock lock(monitor->lock_);
    monitor->bytes_sent_ = 0;
    monitor->bytes_received_ = 0;
    monitor->last_received_ticks_ = base::TimeTicks();
    monitor->last_sent_ticks_ = base::TimeTicks();
  }
};


class NetworkActivityMontiorTest : public testing::Test {
 public:
  NetworkActivityMontiorTest() {
    NetworkActivityMonitorPeer::ResetMonitor();
  }
};

TEST_F(NetworkActivityMontiorTest, GetInstance) {
  NetworkActivityMonitor* monitor = NetworkActivityMonitor::GetInstance();
  EXPECT_TRUE(monitor != NULL);
  EXPECT_TRUE(monitor == NetworkActivityMonitor::GetInstance());
}

TEST_F(NetworkActivityMontiorTest, BytesReceived) {
  NetworkActivityMonitor* monitor = NetworkActivityMonitor::GetInstance();

  EXPECT_EQ(0u, monitor->GetBytesReceived());

  base::TimeTicks start = base::TimeTicks::Now();
  uint64_t bytes = 12345;
  monitor->IncrementBytesReceived(bytes);
  EXPECT_EQ(bytes, monitor->GetBytesReceived());
  base::TimeDelta delta = monitor->GetTimeSinceLastReceived();
  EXPECT_LE(base::TimeDelta(), delta);
  EXPECT_GE(base::TimeTicks::Now() - start, delta);
}

TEST_F(NetworkActivityMontiorTest, BytesSent) {
  NetworkActivityMonitor* monitor = NetworkActivityMonitor::GetInstance();

  EXPECT_EQ(0u, monitor->GetBytesSent());

  base::TimeTicks start = base::TimeTicks::Now();
  uint64_t bytes = 12345;
  monitor->IncrementBytesSent(bytes);
  EXPECT_EQ(bytes, monitor->GetBytesSent());
  base::TimeDelta delta = monitor->GetTimeSinceLastSent();
  EXPECT_LE(base::TimeDelta(), delta);
  EXPECT_GE(base::TimeTicks::Now() - start, delta);
}

namespace {

void VerifyBytesReceivedIsMultipleOf(uint64_t bytes) {
  EXPECT_EQ(0u,
            NetworkActivityMonitor::GetInstance()->GetBytesReceived() % bytes);
}

void VerifyBytesSentIsMultipleOf(uint64_t bytes) {
  EXPECT_EQ(0u, NetworkActivityMonitor::GetInstance()->GetBytesSent() % bytes);
}

void IncrementBytesReceived(uint64_t bytes) {
  NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(bytes);
}

void IncrementBytesSent(uint64_t bytes) {
  NetworkActivityMonitor::GetInstance()->IncrementBytesSent(bytes);
}

}  // namespace

TEST_F(NetworkActivityMontiorTest, Threading) {
  std::vector<base::Thread*> threads;
  for (size_t i = 0; i < 3; ++i) {
    threads.push_back(new base::Thread(base::UintToString(i)));
    ASSERT_TRUE(threads.back()->Start());
  }

  size_t num_increments = 157;
  uint64_t bytes_received = GG_UINT64_C(7294954321);
  uint64_t bytes_sent = GG_UINT64_C(91294998765);
  for (size_t i = 0; i < num_increments; ++i) {
    size_t thread_num = i % threads.size();
    threads[thread_num]->task_runner()->PostTask(
        FROM_HERE,
        base::Bind(&IncrementBytesReceived, bytes_received));
    threads[thread_num]->task_runner()->PostTask(
        FROM_HERE,
        base::Bind(&IncrementBytesSent, bytes_sent));
    threads[thread_num]->task_runner()->PostTask(
        FROM_HERE,
        base::Bind(&VerifyBytesSentIsMultipleOf, bytes_sent));
    threads[thread_num]->task_runner()->PostTask(
        FROM_HERE,
        base::Bind(&VerifyBytesReceivedIsMultipleOf, bytes_received));
  }

  STLDeleteElements(&threads);

  NetworkActivityMonitor* monitor = NetworkActivityMonitor::GetInstance();
  EXPECT_EQ(num_increments * bytes_received, monitor->GetBytesReceived());
  EXPECT_EQ(num_increments * bytes_sent, monitor->GetBytesSent());
}

}  // namespace test

}  // namespace net
