/*
 *  Copyright (c) 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.
 */
#ifndef API_TEST_NETWORK_EMULATION_NETWORK_EMULATION_INTERFACES_H_
#define API_TEST_NETWORK_EMULATION_NETWORK_EMULATION_INTERFACES_H_

#include <map>
#include <memory>
#include <vector>

#include "absl/types/optional.h"
#include "api/array_view.h"
#include "api/numerics/samples_stats_counter.h"
#include "api/units/data_rate.h"
#include "api/units/data_size.h"
#include "api/units/timestamp.h"
#include "rtc_base/copy_on_write_buffer.h"
#include "rtc_base/ip_address.h"
#include "rtc_base/socket_address.h"

namespace webrtc {

struct EmulatedIpPacket {
 public:
  EmulatedIpPacket(const rtc::SocketAddress& from,
                   const rtc::SocketAddress& to,
                   rtc::CopyOnWriteBuffer data,
                   Timestamp arrival_time,
                   uint16_t application_overhead = 0);
  ~EmulatedIpPacket() = default;
  // This object is not copyable or assignable.
  EmulatedIpPacket(const EmulatedIpPacket&) = delete;
  EmulatedIpPacket& operator=(const EmulatedIpPacket&) = delete;
  // This object is only moveable.
  EmulatedIpPacket(EmulatedIpPacket&&) = default;
  EmulatedIpPacket& operator=(EmulatedIpPacket&&) = default;

  size_t size() const { return data.size(); }
  const uint8_t* cdata() const { return data.cdata(); }

  size_t ip_packet_size() const { return size() + headers_size; }
  rtc::SocketAddress from;
  rtc::SocketAddress to;
  // Holds the UDP payload.
  rtc::CopyOnWriteBuffer data;
  uint16_t headers_size;
  Timestamp arrival_time;
};

// Interface for handling IP packets from an emulated network. This is used with
// EmulatedEndpoint to receive packets on a specific port.
class EmulatedNetworkReceiverInterface {
 public:
  virtual ~EmulatedNetworkReceiverInterface() = default;

  virtual void OnPacketReceived(EmulatedIpPacket packet) = 0;
};

struct EmulatedNetworkOutgoingStats {
  int64_t packets_sent = 0;

  DataSize bytes_sent = DataSize::Zero();

  // Sizes of all sent packets.
  // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
  SamplesStatsCounter sent_packets_size;

  DataSize first_sent_packet_size = DataSize::Zero();

  // Time of the first packet sent or infinite value if no packets were sent.
  Timestamp first_packet_sent_time = Timestamp::PlusInfinity();

  // Time of the last packet sent or infinite value if no packets were sent.
  Timestamp last_packet_sent_time = Timestamp::MinusInfinity();

  // Returns average send rate. Requires that at least 2 packets were sent.
  DataRate AverageSendRate() const;
};

struct EmulatedNetworkIncomingStats {
  // Total amount of packets received with or without destination.
  int64_t packets_received = 0;

  // Total amount of bytes in received packets.
  DataSize bytes_received = DataSize::Zero();

  // Sizes of all received packets.
  // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
  SamplesStatsCounter received_packets_size;

  // Total amount of packets that were received, but no destination was found.
  int64_t packets_discarded_no_receiver = 0;

  // Total amount of bytes in discarded packets.
  DataSize bytes_discarded_no_receiver = DataSize::Zero();

  // Sizes of all packets that were received, but no destination was found.
  // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
  SamplesStatsCounter packets_discarded_no_receiver_size;

  DataSize first_received_packet_size = DataSize::Zero();

  // Time of the first packet received or infinite value if no packets were
  // received.
  Timestamp first_packet_received_time = Timestamp::PlusInfinity();

  // Time of the last packet received or infinite value if no packets were
  // received.
  Timestamp last_packet_received_time = Timestamp::MinusInfinity();

  DataRate AverageReceiveRate() const;
};

struct EmulatedNetworkStats {
  int64_t PacketsSent() const { return overall_outgoing_stats.packets_sent; }

  DataSize BytesSent() const { return overall_outgoing_stats.bytes_sent; }

  // Returns the timestamped sizes of all sent packets.
  // Returned reference is valid until the next call to a non-const method.
  // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
  const SamplesStatsCounter& SentPacketsSizeCounter() const {
    return overall_outgoing_stats.sent_packets_size;
  }

  DataSize FirstSentPacketSize() const {
    return overall_outgoing_stats.first_sent_packet_size;
  }

  // Returns time of the first packet sent or infinite value if no packets were
  // sent.
  Timestamp FirstPacketSentTime() const {
    return overall_outgoing_stats.first_packet_sent_time;
  }

  // Returns time of the last packet sent or infinite value if no packets were
  // sent.
  Timestamp LastPacketSentTime() const {
    return overall_outgoing_stats.last_packet_sent_time;
  }

  DataRate AverageSendRate() const {
    return overall_outgoing_stats.AverageSendRate();
  }

  // Total amount of packets received regardless of the destination address.
  int64_t PacketsReceived() const {
    return overall_incoming_stats.packets_received;
  }

  // Total amount of bytes in received packets.
  DataSize BytesReceived() const {
    return overall_incoming_stats.bytes_received;
  }

  // Returns the timestamped sizes of all received packets.
  // Returned reference is valid until the next call to a non-const method.
  // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
  const SamplesStatsCounter& ReceivedPacketsSizeCounter() const {
    return overall_incoming_stats.received_packets_size;
  }

  // Total amount of packets that were received, but no destination was found.
  int64_t PacketsDiscardedNoReceiver() const {
    return overall_incoming_stats.packets_discarded_no_receiver;
  }

  // Total amount of bytes in dropped packets.
  DataSize BytesDiscardedNoReceiver() const {
    return overall_incoming_stats.bytes_discarded_no_receiver;
  }

  // Returns counter with timestamped sizes of all packets that were received,
  // but no destination was found.
  // Returned reference is valid until the next call to a non-const method.
  // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
  const SamplesStatsCounter& PacketsDiscardedNoReceiverSizeCounter() const {
    return overall_incoming_stats.packets_discarded_no_receiver_size;
  }

  DataSize FirstReceivedPacketSize() const {
    return overall_incoming_stats.first_received_packet_size;
  }

  // Returns time of the first packet received or infinite value if no packets
  // were received.
  Timestamp FirstPacketReceivedTime() const {
    return overall_incoming_stats.first_packet_received_time;
  }

  // Returns time of the last packet received or infinite value if no packets
  // were received.
  Timestamp LastPacketReceivedTime() const {
    return overall_incoming_stats.last_packet_received_time;
  }

  DataRate AverageReceiveRate() const {
    return overall_incoming_stats.AverageReceiveRate();
  }

  // List of IP addresses that were used to send data considered in this stats
  // object.
  std::vector<rtc::IPAddress> local_addresses;

  // Overall outgoing stats for all IP addresses which were requested.
  EmulatedNetworkOutgoingStats overall_outgoing_stats;

  // Overall incoming stats for all IP addresses from which data was received
  // on requested interfaces.
  EmulatedNetworkIncomingStats overall_incoming_stats;

  std::map<rtc::IPAddress, EmulatedNetworkOutgoingStats>
      outgoing_stats_per_destination;
  std::map<rtc::IPAddress, EmulatedNetworkIncomingStats>
      incoming_stats_per_source;

  // Duration between packet was received on network interface and was
  // dispatched to the network in microseconds.
  // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
  SamplesStatsCounter sent_packets_queue_wait_time_us;
};

struct EmulatedNetworkNodeStats {
  // Amount of time each packet spent in the emulated network node for which
  // stats were collected.
  //
  // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
  SamplesStatsCounter packet_transport_time;

  // For each packet contains its size divided on the amount of time which it
  // spent in the emulated network node for which stats were collected.
  //
  // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
  SamplesStatsCounter size_to_packet_transport_time;
};

// EmulatedEndpoint is an abstraction for network interface on device. Instances
// of this are created by NetworkEmulationManager::CreateEndpoint and
// thread safe.
class EmulatedEndpoint : public EmulatedNetworkReceiverInterface {
 public:
  // Send packet into network.
  // `from` will be used to set source address for the packet in destination
  // socket.
  // `to` will be used for routing verification and picking right socket by port
  // on destination endpoint.
  virtual void SendPacket(const rtc::SocketAddress& from,
                          const rtc::SocketAddress& to,
                          rtc::CopyOnWriteBuffer packet_data,
                          uint16_t application_overhead = 0) = 0;

  // Binds receiver to this endpoint to send and receive data.
  // `desired_port` is a port that should be used. If it is equal to 0,
  // endpoint will pick the first available port starting from
  // `kFirstEphemeralPort`.
  //
  // Returns the port, that should be used (it will be equals to desired, if
  // `desired_port` != 0 and is free or will be the one, selected by endpoint)
  // or absl::nullopt if desired_port in used. Also fails if there are no more
  // free ports to bind to.
  //
  // The Bind- and Unbind-methods must not be called from within a bound
  // receiver's OnPacketReceived method.
  virtual absl::optional<uint16_t> BindReceiver(
      uint16_t desired_port,
      EmulatedNetworkReceiverInterface* receiver) = 0;
  // Unbinds receiver from the specified port. Do nothing if no receiver was
  // bound before. After this method returns, no more packets can be delivered
  // to the receiver, and it is safe to destroy it.
  virtual void UnbindReceiver(uint16_t port) = 0;
  // Binds receiver that will accept all packets which arrived on any port
  // for which there are no bound receiver.
  virtual void BindDefaultReceiver(
      EmulatedNetworkReceiverInterface* receiver) = 0;
  // Unbinds default receiver. Do nothing if no default receiver was bound
  // before.
  virtual void UnbindDefaultReceiver() = 0;
  virtual rtc::IPAddress GetPeerLocalAddress() const = 0;

 private:
  // Ensure that there can be no other subclass than EmulatedEndpointImpl. This
  // means that it's always safe to downcast EmulatedEndpoint instances to
  // EmulatedEndpointImpl.
  friend class EmulatedEndpointImpl;
  EmulatedEndpoint() = default;
};

// Simulates a TCP connection, this roughly implements the Reno algorithm. In
// difference from TCP this only support sending messages with a fixed length,
// no streaming. This is useful to simulate signaling and cross traffic using
// message based protocols such as HTTP. It differs from UDP messages in that
// they are guranteed to be delivered eventually, even on lossy networks.
class TcpMessageRoute {
 public:
  // Sends a TCP message of the given `size` over the route, `on_received` is
  // called when the message has been delivered. Note that the connection
  // parameters are reset iff there's no currently pending message on the route.
  virtual void SendMessage(size_t size, std::function<void()> on_received) = 0;

 protected:
  ~TcpMessageRoute() = default;
};
}  // namespace webrtc

#endif  // API_TEST_NETWORK_EMULATION_NETWORK_EMULATION_INTERFACES_H_
