/*
 *  Copyright (c) 2018 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.
 */

#ifndef API_TEST_SIMULATED_NETWORK_H_
#define API_TEST_SIMULATED_NETWORK_H_

#include <stddef.h>
#include <stdint.h>

#include <deque>
#include <queue>
#include <vector>

#include "absl/types/optional.h"
#include "rtc_base/random.h"
#include "rtc_base/thread_annotations.h"

namespace webrtc {

struct PacketInFlightInfo {
  PacketInFlightInfo(size_t size, int64_t send_time_us, uint64_t packet_id)
      : size(size), send_time_us(send_time_us), packet_id(packet_id) {}

  size_t size;
  int64_t send_time_us;
  // Unique identifier for the packet in relation to other packets in flight.
  uint64_t packet_id;
};

struct PacketDeliveryInfo {
  static constexpr int kNotReceived = -1;
  PacketDeliveryInfo(PacketInFlightInfo source, int64_t receive_time_us)
      : receive_time_us(receive_time_us), packet_id(source.packet_id) {}

  bool operator==(const PacketDeliveryInfo& other) const {
    return receive_time_us == other.receive_time_us &&
           packet_id == other.packet_id;
  }

  int64_t receive_time_us;
  uint64_t packet_id;
};

// BuiltInNetworkBehaviorConfig is a built-in network behavior configuration
// for built-in network behavior that will be used by WebRTC if no custom
// NetworkBehaviorInterface is provided.
struct BuiltInNetworkBehaviorConfig {
  //  Queue length in number of packets.
  size_t queue_length_packets = 0;
  // Delay in addition to capacity induced delay.
  int queue_delay_ms = 0;
  // Standard deviation of the extra delay.
  int delay_standard_deviation_ms = 0;
  // Link capacity in kbps.
  int link_capacity_kbps = 0;
  // Random packet loss, range 0 to 100.
  double loss_percent = 0.;
  // If packets are allowed to be reordered.
  bool allow_reordering = false;
  // The average length of a burst of lost packets.
  int avg_burst_loss_length = -1;
  // Additional bytes to add to packet size.
  int packet_overhead = 0;
};

// Interface that represents a Network behaviour.
//
// It is clients of this interface responsibility to enqueue and dequeue
// packets (based on the estimated delivery time expressed by
// NextDeliveryTimeUs).
//
// To enqueue packets, call EnqueuePacket:
// EXPECT_TRUE(network.EnqueuePacket(
//     PacketInFlightInfo(/*size=*/1, /*send_time_us=*/0, /*packet_id=*/1)));
//
// To know when to call DequeueDeliverablePackets to pull packets out of the
// network, call NextDeliveryTimeUs and schedule a task to invoke
// DequeueDeliverablePackets (if not already scheduled).
//
// DequeueDeliverablePackets will return a vector of delivered packets, but this
// vector can be empty in case of extra delay. In such case, make sure to invoke
// NextDeliveryTimeUs and schedule a task to call DequeueDeliverablePackets for
// the next estimated delivery of packets.
//
// std::vector<PacketDeliveryInfo> delivered_packets =
//     network.DequeueDeliverablePackets(/*receive_time_us=*/1000000);
class NetworkBehaviorInterface {
 public:
  // Enqueues a packet in the network and returns true if the action was
  // successful, false otherwise (for example, because the network capacity has
  // been saturated). If the return value is false, the packet should be
  // considered as dropped and it will not be returned by future calls
  // to DequeueDeliverablePackets.
  // Packets enqueued will exit the network when DequeueDeliverablePackets is
  // called and enough time has passed (see NextDeliveryTimeUs).
  virtual bool EnqueuePacket(PacketInFlightInfo packet_info) = 0;
  // Retrieves all packets that should be delivered by the given receive time.
  // Not all the packets in the returned std::vector are actually delivered.
  // In order to know the state of each packet it is necessary to check the
  // `receive_time_us` field of each packet. If that is set to
  // PacketDeliveryInfo::kNotReceived then the packet is considered lost in the
  // network.
  virtual std::vector<PacketDeliveryInfo> DequeueDeliverablePackets(
      int64_t receive_time_us) = 0;
  // Returns time in microseconds when caller should call
  // DequeueDeliverablePackets to get the next set of delivered packets. It is
  // possible that no packet will be delivered by that time (e.g. in case of
  // random extra delay), in such case this method should be called again to get
  // the updated estimated delivery time.
  virtual absl::optional<int64_t> NextDeliveryTimeUs() const = 0;
  virtual ~NetworkBehaviorInterface() = default;
};

// Class simulating a network link. This is a simple and naive solution just
// faking capacity and adding an extra transport delay in addition to the
// capacity introduced delay.
class SimulatedNetworkInterface : public NetworkBehaviorInterface {
 public:
  // Sets a new configuration.
  virtual void SetConfig(const BuiltInNetworkBehaviorConfig& config) = 0;
  virtual void UpdateConfig(
      std::function<void(BuiltInNetworkBehaviorConfig*)> config_modifier) = 0;
  // Pauses the network until `until_us`. This affects both delivery (calling
  // DequeueDeliverablePackets before `until_us` results in an empty std::vector
  // of packets) and capacity (the network is paused, so packets are not
  // flowing and they will restart flowing at `until_us`).
  virtual void PauseTransmissionUntil(int64_t until_us) = 0;
};

}  // namespace webrtc

#endif  // API_TEST_SIMULATED_NETWORK_H_
