/*
 *  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 "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, &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::ms(25);
  config.send_duration = TimeDelta::ms(500);
  config.hold_duration = TimeDelta::ms(250);
  PulsedPeaksCrossTraffic pulsed_peaks(config, &traffic);
  const auto kRunTime = TimeDelta::seconds(1);
  while (fixture.clock.TimeInMilliseconds() < kRunTime.ms()) {
    pulsed_peaks.Process(Timestamp::ms(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::ms(25);
  config.update_interval = TimeDelta::ms(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::ms(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
