/*
 *  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 TEST_NETWORK_NETWORK_EMULATION_H_
#define TEST_NETWORK_NETWORK_EMULATION_H_

#include <cstdint>
#include <cstring>
#include <deque>
#include <functional>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "absl/base/nullability.h"
#include "api/numerics/samples_stats_counter.h"
#include "api/sequence_checker.h"
#include "api/task_queue/task_queue_base.h"
#include "api/test/network_emulation/network_emulation_interfaces.h"
#include "api/test/network_emulation_manager.h"
#include "api/test/simulated_network.h"
#include "api/transport/ecn_marking.h"
#include "api/units/data_size.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "rtc_base/checks.h"
#include "rtc_base/copy_on_write_buffer.h"
#include "rtc_base/ip_address.h"
#include "rtc_base/network.h"
#include "rtc_base/network_constants.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/synchronization/mutex.h"
#include "rtc_base/system/no_unique_address.h"
#include "rtc_base/task_utils/repeating_task.h"
#include "rtc_base/thread_annotations.h"
#include "system_wrappers/include/clock.h"

namespace webrtc {

// All methods of EmulatedNetworkOutgoingStatsBuilder have to be used on a
// single thread. It may be created on another thread.
class EmulatedNetworkOutgoingStatsBuilder {
 public:
  explicit EmulatedNetworkOutgoingStatsBuilder(
      EmulatedNetworkStatsGatheringMode stats_gathering_mode);

  void OnPacketSent(Timestamp sent_time, const EmulatedIpPacket& packet);

  void AddOutgoingStats(const EmulatedNetworkOutgoingStats& stats);

  EmulatedNetworkOutgoingStats Build() const;

 private:
  const EmulatedNetworkStatsGatheringMode stats_gathering_mode_;

  RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
  EmulatedNetworkOutgoingStats stats_ RTC_GUARDED_BY(sequence_checker_);
};

// All methods of EmulatedNetworkIncomingStatsBuilder have to be used on a
// single thread. It may be created on another thread.
class EmulatedNetworkIncomingStatsBuilder {
 public:
  explicit EmulatedNetworkIncomingStatsBuilder(
      Clock& clock,
      EmulatedNetworkStatsGatheringMode stats_gathering_mode);

  void OnPacketDropped(DataSize packet_size);

  void OnPacketReceived(Timestamp received_time,
                        const EmulatedIpPacket& packet);

  // Adds stats collected from another endpoints to the builder.
  void AddIncomingStats(const EmulatedNetworkIncomingStats& stats);

  EmulatedNetworkIncomingStats Build() const;

 private:
  Clock& clock_;
  const EmulatedNetworkStatsGatheringMode stats_gathering_mode_;

  RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
  EmulatedNetworkIncomingStats stats_ RTC_GUARDED_BY(sequence_checker_);
};

// All methods of EmulatedNetworkStatsBuilder have to be used on a single
// thread. It may be created on another thread.
class EmulatedNetworkStatsBuilder {
 public:
  explicit EmulatedNetworkStatsBuilder(
      Clock& clock,
      EmulatedNetworkStatsGatheringMode stats_gathering_mode);
  explicit EmulatedNetworkStatsBuilder(
      Clock& clock,
      IPAddress local_ip,
      EmulatedNetworkStatsGatheringMode stats_gathering_mode);

  void OnPacketSent(Timestamp send_time, const EmulatedIpPacket& packet);

  void OnPacketDropped(IPAddress source_ip, DataSize packet_size);

  void OnPacketReceived(Timestamp received_time,
                        const EmulatedIpPacket& packet);

  void AddEmulatedNetworkStats(const EmulatedNetworkStats& stats);

  EmulatedNetworkStats Build() const;

 private:
  Clock& clock_;
  const EmulatedNetworkStatsGatheringMode stats_gathering_mode_;

  RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
  std::vector<IPAddress> local_addresses_ RTC_GUARDED_BY(sequence_checker_);
  SamplesStatsCounter sent_packets_queue_wait_time_us_;
  std::map<IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStatsBuilder>>
      outgoing_stats_per_destination_ RTC_GUARDED_BY(sequence_checker_);
  std::map<IPAddress, std::unique_ptr<EmulatedNetworkIncomingStatsBuilder>>
      incoming_stats_per_source_ RTC_GUARDED_BY(sequence_checker_);
};

// All methods of EmulatedNetworkNodeStatsBuilder have to be used on a
// single thread. It may be created on another thread.
class EmulatedNetworkNodeStatsBuilder {
 public:
  explicit EmulatedNetworkNodeStatsBuilder(
      Clock& clock,
      EmulatedNetworkStatsGatheringMode stats_gathering_mode);

  void AddPacketTransportTime(TimeDelta time, size_t packet_size);

  void AddEmulatedNetworkNodeStats(const EmulatedNetworkNodeStats& stats);

  EmulatedNetworkNodeStats Build() const;

 private:
  Clock& clock_;
  const EmulatedNetworkStatsGatheringMode stats_gathering_mode_;

  RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
  EmulatedNetworkNodeStats stats_ RTC_GUARDED_BY(sequence_checker_);
};

class LinkEmulation : public EmulatedNetworkReceiverInterface {
 public:
  LinkEmulation(Clock* clock,
                TaskQueueBase* absl_nonnull task_queue,
                std::unique_ptr<NetworkBehaviorInterface> network_behavior,
                EmulatedNetworkReceiverInterface* receiver,
                EmulatedNetworkStatsGatheringMode stats_gathering_mode,
                bool fake_dtls_handshake_sizes);
  void OnPacketReceived(EmulatedIpPacket packet) override;

  EmulatedNetworkNodeStats stats() const;

 private:
  struct StoredPacket {
    uint64_t id;
    Timestamp sent_time;
    EmulatedIpPacket packet;
    bool removed;
  };
  void UpdateProcessSchedule() RTC_RUN_ON(task_queue_);
  void Process(Timestamp at_time) RTC_RUN_ON(task_queue_);
  size_t GetPacketSizeForEmulation(const EmulatedIpPacket& packet) const;

  Clock* const clock_;
  TaskQueueBase* absl_nonnull const task_queue_;
  const std::unique_ptr<NetworkBehaviorInterface> network_behavior_
      RTC_GUARDED_BY(task_queue_);
  EmulatedNetworkReceiverInterface* const receiver_;
  const bool fake_dtls_handshake_sizes_;

  RepeatingTaskHandle process_task_ RTC_GUARDED_BY(task_queue_);
  std::deque<StoredPacket> packets_ RTC_GUARDED_BY(task_queue_);
  uint64_t next_packet_id_ RTC_GUARDED_BY(task_queue_) = 1;

  EmulatedNetworkNodeStatsBuilder stats_builder_ RTC_GUARDED_BY(task_queue_);
};

// Represents a component responsible for routing packets based on their IP
// address. All possible routes have to be set explicitly before packet for
// desired destination will be seen for the first time. If route is unknown
// the packet will be silently dropped.
class NetworkRouterNode : public EmulatedNetworkReceiverInterface {
 public:
  explicit NetworkRouterNode(TaskQueueBase* absl_nonnull task_queue);

  void OnPacketReceived(EmulatedIpPacket packet) override;
  void SetReceiver(const IPAddress& dest_ip,
                   EmulatedNetworkReceiverInterface* receiver);
  void RemoveReceiver(const IPAddress& dest_ip);
  // Sets a default receive that will be used for all incoming packets for which
  // there is no specific receiver binded to their destination port.
  void SetDefaultReceiver(EmulatedNetworkReceiverInterface* receiver);
  void RemoveDefaultReceiver();
  void SetWatcher(std::function<void(const EmulatedIpPacket&)> watcher);
  void SetFilter(std::function<bool(const EmulatedIpPacket&)> filter);

 private:
  TaskQueueBase* absl_nonnull const task_queue_;
  std::optional<EmulatedNetworkReceiverInterface*> default_receiver_
      RTC_GUARDED_BY(task_queue_);
  std::map<IPAddress, EmulatedNetworkReceiverInterface*> routing_
      RTC_GUARDED_BY(task_queue_);
  std::function<void(const EmulatedIpPacket&)> watcher_
      RTC_GUARDED_BY(task_queue_);
  std::function<bool(const EmulatedIpPacket&)> filter_
      RTC_GUARDED_BY(task_queue_);
};

// Represents node in the emulated network. Nodes can be connected with each
// other to form different networks with different behavior. The behavior of
// the node itself is determined by a concrete implementation of
// NetworkBehaviorInterface that is provided on construction.
class EmulatedNetworkNode : public EmulatedNetworkReceiverInterface {
 public:
  // Creates node based on `network_behavior`. The specified `packet_overhead`
  // is added to the size of each packet in the information provided to
  // `network_behavior`.
  // `task_queue` is used to process packets and to forward the packets when
  // they are ready.
  EmulatedNetworkNode(
      Clock* clock,
      TaskQueueBase* absl_nonnull task_queue,
      std::unique_ptr<NetworkBehaviorInterface> network_behavior,
      EmulatedNetworkStatsGatheringMode stats_gathering_mode,
      bool fake_dtls_handshake_sizes);
  ~EmulatedNetworkNode() override;

  EmulatedNetworkNode(const EmulatedNetworkNode&) = delete;
  EmulatedNetworkNode& operator=(const EmulatedNetworkNode&) = delete;

  void OnPacketReceived(EmulatedIpPacket packet) override;

  LinkEmulation* link() { return &link_; }
  NetworkRouterNode* router() { return &router_; }
  EmulatedNetworkNodeStats stats() const;

  // Creates a route for the given receiver_ip over all the given nodes to the
  // given receiver.
  static void CreateRoute(const IPAddress& receiver_ip,
                          std::vector<EmulatedNetworkNode*> nodes,
                          EmulatedNetworkReceiverInterface* receiver);
  static void ClearRoute(const IPAddress& receiver_ip,
                         std::vector<EmulatedNetworkNode*> nodes);

 private:
  NetworkRouterNode router_;
  LinkEmulation link_;
};

// Represents single network interface on the device.
// It will be used as sender from socket side to send data to the network and
// will act as packet receiver from emulated network side to receive packets
// from other EmulatedNetworkNodes.
class EmulatedEndpointImpl : public EmulatedEndpoint {
 public:
  struct Options {
    Options(uint64_t id,
            const IPAddress& ip,
            const EmulatedEndpointConfig& config,
            EmulatedNetworkStatsGatheringMode stats_gathering_mode);

    // TODO(titovartem) check if we can remove id.
    uint64_t id;
    // Endpoint local IP address.
    IPAddress ip;
    EmulatedNetworkStatsGatheringMode stats_gathering_mode;
    AdapterType type;
    // Allow endpoint to send packets specifying source IP address different to
    // the current endpoint IP address. If false endpoint will crash if attempt
    // to send such packet will be done.
    bool allow_send_packet_with_different_source_ip;
    // Allow endpoint to receive packet with destination IP address different to
    // the current endpoint IP address. If false endpoint will crash if such
    // packet will arrive.
    bool allow_receive_packets_with_different_dest_ip;
    // Name of the endpoint used for logging purposes.
    std::string log_name;
  };

  EmulatedEndpointImpl(const Options& options,
                       bool is_enabled,
                       TaskQueueBase* absl_nonnull task_queue,
                       Clock* clock);
  ~EmulatedEndpointImpl() override;

  uint64_t GetId() const;

  NetworkRouterNode* router() { return &router_; }

  void SendPacket(const SocketAddress& from,
                  const SocketAddress& to,
                  CopyOnWriteBuffer packet_data,
                  uint16_t application_overhead = 0,
                  EcnMarking ecn = EcnMarking::kNotEct) override;

  std::optional<uint16_t> BindReceiver(
      uint16_t desired_port,
      EmulatedNetworkReceiverInterface* receiver) override;
  // Binds a receiver, and automatically removes the binding after first call to
  // OnPacketReceived.
  std::optional<uint16_t> BindOneShotReceiver(
      uint16_t desired_port,
      EmulatedNetworkReceiverInterface* receiver);
  void UnbindReceiver(uint16_t port) override;
  void BindDefaultReceiver(EmulatedNetworkReceiverInterface* receiver) override;
  void UnbindDefaultReceiver() override;

  IPAddress GetPeerLocalAddress() const override;

  // Will be called to deliver packet into endpoint from network node.
  void OnPacketReceived(EmulatedIpPacket packet) override;

  void Enable();
  void Disable();
  bool Enabled() const;

  const Network& network() const { return *network_; }

  EmulatedNetworkStats stats() const;

 private:
  struct ReceiverBinding {
    EmulatedNetworkReceiverInterface* receiver;
    bool is_one_shot;
  };

  std::optional<uint16_t> BindReceiverInternal(
      uint16_t desired_port,
      EmulatedNetworkReceiverInterface* receiver,
      bool is_one_shot);

  static constexpr uint16_t kFirstEphemeralPort = 49152;
  uint16_t NextPort() RTC_EXCLUSIVE_LOCKS_REQUIRED(receiver_lock_);

  Mutex receiver_lock_;
  mutable Mutex enable_state_mutex_;

  const Options options_;
  bool is_enabled_ RTC_GUARDED_BY(enable_state_mutex_);
  Clock* const clock_;
  TaskQueueBase* absl_nonnull const task_queue_;
  std::unique_ptr<Network> network_;
  NetworkRouterNode router_;

  uint16_t next_port_ RTC_GUARDED_BY(receiver_lock_);
  std::optional<EmulatedNetworkReceiverInterface*> default_receiver_
      RTC_GUARDED_BY(receiver_lock_);
  std::map<uint16_t, ReceiverBinding> port_to_receiver_
      RTC_GUARDED_BY(receiver_lock_);

  EmulatedNetworkStatsBuilder stats_builder_ RTC_GUARDED_BY(task_queue_);
};

class EmulatedRoute {
 public:
  EmulatedRoute(EmulatedEndpointImpl* from,
                std::vector<EmulatedNetworkNode*> via_nodes,
                EmulatedEndpointImpl* to,
                bool is_default)
      : from(from),
        via_nodes(std::move(via_nodes)),
        to(to),
        active(true),
        is_default(is_default) {}

  EmulatedEndpointImpl* from;
  std::vector<EmulatedNetworkNode*> via_nodes;
  EmulatedEndpointImpl* to;
  bool active;
  bool is_default;
};

// This object is immutable and so thread safe.
class EndpointsContainer {
 public:
  EndpointsContainer(Clock* clock,
                     const std::vector<EmulatedEndpointImpl*>& endpoints,
                     EmulatedNetworkStatsGatheringMode stats_gathering_mode);

  EmulatedEndpointImpl* LookupByLocalAddress(const IPAddress& local_ip) const;
  bool HasEndpoint(EmulatedEndpointImpl* endpoint) const;
  // Returns list of networks for enabled endpoints. Caller takes ownership of
  // returned webrtc::Network objects.
  std::vector<std::unique_ptr<Network>> GetEnabledNetworks() const;
  std::vector<EmulatedEndpoint*> GetEndpoints() const;
  EmulatedNetworkStats GetStats() const;

 private:
  Clock* const clock_;
  const std::vector<EmulatedEndpointImpl*> endpoints_;
  const EmulatedNetworkStatsGatheringMode stats_gathering_mode_;
};

template <typename FakePacketType>
class FakePacketRoute : public EmulatedNetworkReceiverInterface {
 public:
  FakePacketRoute(EmulatedRoute* route,
                  std::function<void(FakePacketType, Timestamp)> action)
      : route_(route),
        action_(std::move(action)),
        send_addr_(route_->from->GetPeerLocalAddress(), 0),
        recv_addr_(route_->to->GetPeerLocalAddress(),
                   *route_->to->BindReceiver(0, this)) {}

  ~FakePacketRoute() override { route_->to->UnbindReceiver(recv_addr_.port()); }

  void SendPacket(size_t size, FakePacketType packet) {
    RTC_CHECK_GE(size, sizeof(int));
    sent_.emplace(next_packet_id_, packet);
    CopyOnWriteBuffer buf(size);
    memset(buf.MutableData(), 0, size);
    reinterpret_cast<int*>(buf.MutableData())[0] = next_packet_id_++;
    route_->from->SendPacket(send_addr_, recv_addr_, buf);
  }

  void OnPacketReceived(EmulatedIpPacket packet) override {
    int packet_id = *reinterpret_cast<const int*>(packet.data.data());
    auto node_handle = sent_.extract(packet_id);
    RTC_CHECK(!node_handle.empty());
    action_(std::move(node_handle.mapped()), packet.arrival_time);
  }

 private:
  EmulatedRoute* const route_;
  const std::function<void(FakePacketType, Timestamp)> action_;
  const SocketAddress send_addr_;
  const SocketAddress recv_addr_;
  int next_packet_id_ = 0;
  std::map<int, FakePacketType> sent_;
};

template <typename RequestPacketType, typename ResponsePacketType>
class TwoWayFakeTrafficRoute {
 public:
  class TrafficHandlerInterface {
   public:
    virtual void OnRequest(RequestPacketType, Timestamp) = 0;
    virtual void OnResponse(ResponsePacketType, Timestamp) = 0;
    virtual ~TrafficHandlerInterface() = default;
  };
  TwoWayFakeTrafficRoute(TrafficHandlerInterface* handler,
                         EmulatedRoute* send_route,
                         EmulatedRoute* ret_route)
      : handler_(handler),
        request_handler_{send_route,
                         [&](RequestPacketType packet, Timestamp arrival_time) {
                           handler_->OnRequest(std::move(packet), arrival_time);
                         }},
        response_handler_{
            ret_route, [&](ResponsePacketType packet, Timestamp arrival_time) {
              handler_->OnResponse(std::move(packet), arrival_time);
            }} {}
  void SendRequest(size_t size, RequestPacketType packet) {
    request_handler_.SendPacket(size, std::move(packet));
  }
  void SendResponse(size_t size, ResponsePacketType packet) {
    response_handler_.SendPacket(size, std::move(packet));
  }

 private:
  TrafficHandlerInterface* handler_;
  FakePacketRoute<RequestPacketType> request_handler_;
  FakePacketRoute<ResponsePacketType> response_handler_;
};
}  // namespace webrtc

#endif  // TEST_NETWORK_NETWORK_EMULATION_H_
