/*
 *  Copyright 2019 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "test/network/cross_traffic.h"

#include <atomic>
#include <memory>
#include <utility>
#include <vector>

#include "absl/memory/memory.h"
#include "api/test/simulated_network.h"
#include "call/simulated_network.h"
#include "rtc_base/event.h"
#include "rtc_base/logging.h"
#include "rtc_base/network_constants.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/network/network_emulation_manager.h"
#include "test/time_controller/simulated_time_controller.h"

namespace webrtc {
namespace test {
namespace {

constexpr uint32_t kTestIpAddress = 0xC0A80011;  // 192.168.0.17

class CountingReceiver : public EmulatedNetworkReceiverInterface {
 public:
  void OnPacketReceived(EmulatedIpPacket packet) override {
    packets_count_++;
    total_packets_size_ += packet.size();
  }

  std::atomic<int> packets_count_{0};
  std::atomic<uint64_t> total_packets_size_{0};
};
struct TrafficCounterFixture {
  SimulatedClock clock{0};
  CountingReceiver counter;
  TaskQueueForTest task_queue_;
  EmulatedEndpointImpl endpoint{/*id=*/1,
                                rtc::IPAddress(kTestIpAddress),
                                /*is_enabled=*/true,
                                /*type=*/rtc::AdapterType::ADAPTER_TYPE_UNKNOWN,
                                &task_queue_,
                                &clock};
};

}  // namespace

TEST(CrossTrafficTest, TriggerPacketBurst) {
  TrafficCounterFixture fixture;
  TrafficRoute traffic(&fixture.clock, &fixture.counter, &fixture.endpoint);
  traffic.TriggerPacketBurst(100, 1000);

  EXPECT_EQ(fixture.counter.packets_count_, 100);
  EXPECT_EQ(fixture.counter.total_packets_size_, 100 * 1000ul);
}

TEST(CrossTrafficTest, PulsedPeaksCrossTraffic) {
  TrafficCounterFixture fixture;
  TrafficRoute traffic(&fixture.clock, &fixture.counter, &fixture.endpoint);

  PulsedPeaksConfig config;
  config.peak_rate = DataRate::kbps(1000);
  config.min_packet_size = DataSize::bytes(1);
  config.min_packet_interval = TimeDelta::Millis(25);
  config.send_duration = TimeDelta::Millis(500);
  config.hold_duration = TimeDelta::Millis(250);
  PulsedPeaksCrossTraffic pulsed_peaks(config, &traffic);
  const auto kRunTime = TimeDelta::Seconds(1);
  while (fixture.clock.TimeInMilliseconds() < kRunTime.ms()) {
    pulsed_peaks.Process(Timestamp::Millis(fixture.clock.TimeInMilliseconds()));
    fixture.clock.AdvanceTimeMilliseconds(1);
  }

  RTC_LOG(INFO) << fixture.counter.packets_count_ << " packets; "
                << fixture.counter.total_packets_size_ << " bytes";
  // Using 50% duty cycle.
  const auto kExpectedDataSent = kRunTime * config.peak_rate * 0.5;
  EXPECT_NEAR(fixture.counter.total_packets_size_, kExpectedDataSent.bytes(),
              kExpectedDataSent.bytes() * 0.1);
}

TEST(CrossTrafficTest, RandomWalkCrossTraffic) {
  TrafficCounterFixture fixture;
  TrafficRoute traffic(&fixture.clock, &fixture.counter, &fixture.endpoint);

  RandomWalkConfig config;
  config.peak_rate = DataRate::kbps(1000);
  config.min_packet_size = DataSize::bytes(1);
  config.min_packet_interval = TimeDelta::Millis(25);
  config.update_interval = TimeDelta::Millis(500);
  config.variance = 0.0;
  config.bias = 1.0;

  RandomWalkCrossTraffic random_walk(config, &traffic);
  const auto kRunTime = TimeDelta::Seconds(1);
  while (fixture.clock.TimeInMilliseconds() < kRunTime.ms()) {
    random_walk.Process(Timestamp::Millis(fixture.clock.TimeInMilliseconds()));
    fixture.clock.AdvanceTimeMilliseconds(1);
  }

  RTC_LOG(INFO) << fixture.counter.packets_count_ << " packets; "
                << fixture.counter.total_packets_size_ << " bytes";
  // Sending at peak rate since bias = 1.
  const auto kExpectedDataSent = kRunTime * config.peak_rate;
  EXPECT_NEAR(fixture.counter.total_packets_size_, kExpectedDataSent.bytes(),
              kExpectedDataSent.bytes() * 0.1);
}

TEST(TcpMessageRouteTest, DeliveredOnLossyNetwork) {
  NetworkEmulationManagerImpl net(TimeMode::kSimulated);
  BuiltInNetworkBehaviorConfig send;
  // 800 kbps means that the 100 kB message would be delivered in ca 1 second
  // under ideal conditions and no overhead.
  send.link_capacity_kbps = 100 * 8;
  send.loss_percent = 50;
  send.queue_delay_ms = 100;
  send.delay_standard_deviation_ms = 20;
  send.allow_reordering = true;
  auto ret = send;
  ret.loss_percent = 10;

  auto* tcp_route =
      net.CreateTcpRoute(net.CreateRoute({net.CreateEmulatedNode(send)}),
                         net.CreateRoute({net.CreateEmulatedNode(ret)}));
  int deliver_count = 0;
  // 100 kB is more than what fits into a single packet.
  constexpr size_t kMessageSize = 100000;

  tcp_route->SendMessage(kMessageSize, [&] {
    RTC_LOG(LS_INFO) << "Received at " << ToString(net.Now());
    deliver_count++;
  });

  // If there was no loss, we would have delivered the message in ca 1 second,
  // with 50% it should take much longer.
  net.time_controller()->AdvanceTime(TimeDelta::Seconds(5));
  ASSERT_EQ(deliver_count, 0);
  // But given enough time the messsage will be delivered, but only once.
  net.time_controller()->AdvanceTime(TimeDelta::Seconds(60));
  EXPECT_EQ(deliver_count, 1);
}

}  // namespace test
}  // namespace webrtc
