// 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 <memory>
#include <vector>

#include "base/bind.h"
#include "base/strings/string_number_conversions.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread.h"
#include "starboard/types.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<std::unique_ptr<base::Thread>> threads;
  for (size_t i = 0; i < 3; ++i) {
    threads.push_back(std::make_unique<base::Thread>(base::NumberToString(i)));
    ASSERT_TRUE(threads.back()->Start());
  }

  size_t num_increments = 157;
  uint64_t bytes_received = UINT64_C(7294954321);
  uint64_t bytes_sent = 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));
  }

  threads.clear();

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

}  // namespace test

}  // namespace net
