/*
 *  Copyright 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_SCENARIO_NETWORK_NODE_H_
#define TEST_SCENARIO_NETWORK_NODE_H_

#include <deque>
#include <map>
#include <memory>
#include <utility>
#include <vector>

#include "api/call/transport.h"
#include "api/units/timestamp.h"
#include "call/simulated_network.h"
#include "rtc_base/constructormagic.h"
#include "rtc_base/copyonwritebuffer.h"
#include "test/scenario/call_client.h"
#include "test/scenario/column_printer.h"
#include "test/scenario/scenario_config.h"

namespace webrtc {
namespace test {

class NetworkReceiverInterface {
 public:
  virtual bool TryDeliverPacket(rtc::CopyOnWriteBuffer packet,
                                uint64_t receiver,
                                Timestamp at_time) = 0;
  virtual ~NetworkReceiverInterface() = default;
};
class NullReceiver : public NetworkReceiverInterface {
 public:
  bool TryDeliverPacket(rtc::CopyOnWriteBuffer packet,
                        uint64_t receiver,
                        Timestamp at_time) override;
};
class ActionReceiver : public NetworkReceiverInterface {
 public:
  explicit ActionReceiver(std::function<void()> action);
  virtual ~ActionReceiver() = default;
  bool TryDeliverPacket(rtc::CopyOnWriteBuffer packet,
                        uint64_t receiver,
                        Timestamp at_time) override;

 private:
  std::function<void()> action_;
};

// NetworkNode represents one link in a simulated network. It is created by a
// scenario and can be used when setting up audio and video stream sessions.
class NetworkNode : public NetworkReceiverInterface {
 public:
  ~NetworkNode() override;
  RTC_DISALLOW_COPY_AND_ASSIGN(NetworkNode);

  bool TryDeliverPacket(rtc::CopyOnWriteBuffer packet,
                        uint64_t receiver,
                        Timestamp at_time) override;
  // Creates a route  for the given receiver_id over all the given nodes to the
  // given receiver.
  static void Route(int64_t receiver_id,
                    std::vector<NetworkNode*> nodes,
                    NetworkReceiverInterface* receiver);

 protected:
  friend class Scenario;
  friend class AudioStreamPair;
  friend class VideoStreamPair;

  NetworkNode(NetworkNodeConfig config,
              std::unique_ptr<NetworkSimulationInterface> simulation);
  static void ClearRoute(int64_t receiver_id, std::vector<NetworkNode*> nodes);
  void Process(Timestamp at_time);

 private:
  struct StoredPacket {
    rtc::CopyOnWriteBuffer packet_data;
    uint64_t receiver_id;
    uint64_t id;
    bool removed;
  };
  void SetRoute(uint64_t receiver, NetworkReceiverInterface* node);
  void ClearRoute(uint64_t receiver_id);
  rtc::CriticalSection crit_sect_;
  size_t packet_overhead_ RTC_GUARDED_BY(crit_sect_);
  const std::unique_ptr<NetworkSimulationInterface> simulation_
      RTC_GUARDED_BY(crit_sect_);
  std::map<uint64_t, NetworkReceiverInterface*> routing_
      RTC_GUARDED_BY(crit_sect_);
  std::deque<StoredPacket> packets_ RTC_GUARDED_BY(crit_sect_);

  uint64_t next_packet_id_ RTC_GUARDED_BY(crit_sect_) = 1;
};
// SimulationNode is a NetworkNode that expose an interface for changing run
// time behavior of the underlying simulation.
class SimulationNode : public NetworkNode {
 public:
  void UpdateConfig(std::function<void(NetworkNodeConfig*)> modifier);
  void PauseTransmissionUntil(Timestamp until);
  ColumnPrinter ConfigPrinter() const;

 private:
  friend class Scenario;

  SimulationNode(NetworkNodeConfig config,
                 std::unique_ptr<NetworkSimulationInterface> behavior,
                 SimulatedNetwork* simulation);
  static std::unique_ptr<SimulationNode> Create(NetworkNodeConfig config);
  SimulatedNetwork* const simulated_network_;
  NetworkNodeConfig config_;
};

class NetworkNodeTransport : public Transport {
 public:
  NetworkNodeTransport(CallClient* sender,
                       NetworkNode* send_net,
                       uint64_t receiver,
                       DataSize packet_overhead);
  ~NetworkNodeTransport() override;

  bool SendRtp(const uint8_t* packet,
               size_t length,
               const PacketOptions& options) override;
  bool SendRtcp(const uint8_t* packet, size_t length) override;
  uint64_t ReceiverId() const;

 private:
  CallClient* const sender_;
  NetworkNode* const send_net_;
  const uint64_t receiver_id_;
  const DataSize packet_overhead_;
};

// CrossTrafficSource is created by a Scenario and generates cross traffic. It
// provides methods to access and print internal state.
class CrossTrafficSource {
 public:
  DataRate TrafficRate() const;
  ColumnPrinter StatsPrinter();
  ~CrossTrafficSource();

 private:
  friend class Scenario;
  CrossTrafficSource(NetworkReceiverInterface* target,
                     uint64_t receiver_id,
                     CrossTrafficConfig config);
  void Process(Timestamp at_time, TimeDelta delta);

  NetworkReceiverInterface* const target_;
  const uint64_t receiver_id_;
  CrossTrafficConfig config_;
  webrtc::Random random_;

  TimeDelta time_since_update_ = TimeDelta::Zero();
  double intensity_ = 0;
  DataSize pending_size_ = DataSize::Zero();
};
}  // namespace test
}  // namespace webrtc
#endif  // TEST_SCENARIO_NETWORK_NODE_H_
