// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_LINK_H_
#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_LINK_H_

#include <utility>

#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
#include "net/third_party/quiche/src/quic/core/quic_bandwidth.h"
#include "net/third_party/quiche/src/quic/test_tools/simulator/actor.h"
#include "net/third_party/quiche/src/quic/test_tools/simulator/port.h"

namespace quic {
namespace simulator {

// A reliable simplex link between two endpoints with constrained bandwidth.  A
// few microseconds of random delay are added for every packet to avoid
// synchronization issues.
class OneWayLink : public Actor, public ConstrainedPortInterface {
 public:
  OneWayLink(Simulator* simulator,
             std::string name,
             UnconstrainedPortInterface* sink,
             QuicBandwidth bandwidth,
             QuicTime::Delta propagation_delay);
  OneWayLink(const OneWayLink&) = delete;
  OneWayLink& operator=(const OneWayLink&) = delete;
  ~OneWayLink() override;

  void AcceptPacket(std::unique_ptr<Packet> packet) override;
  QuicTime::Delta TimeUntilAvailable() override;
  void Act() override;

  inline QuicBandwidth bandwidth() const { return bandwidth_; }
  inline void set_bandwidth(QuicBandwidth new_bandwidth) {
    bandwidth_ = new_bandwidth;
  }

 protected:
  // Get the value of a random delay imposed on each packet.  By default, this
  // is a short random delay in order to avoid artifical synchronization
  // artifacts during the simulation.  Subclasses may override this behavior
  // (for example, to provide a random component of delay).
  virtual QuicTime::Delta GetRandomDelay(QuicTime::Delta transfer_time);

 private:
  struct QueuedPacket {
    std::unique_ptr<Packet> packet;
    QuicTime dequeue_time;

    QueuedPacket(std::unique_ptr<Packet> packet, QuicTime dequeue_time);
    QueuedPacket(QueuedPacket&& other);
    ~QueuedPacket();
  };

  // Schedule the next packet to be egressed out of the link if there are
  // packets on the link.
  void ScheduleNextPacketDeparture();

  UnconstrainedPortInterface* sink_;
  QuicCircularDeque<QueuedPacket> packets_in_transit_;

  QuicBandwidth bandwidth_;
  const QuicTime::Delta propagation_delay_;

  QuicTime next_write_at_;
};

// A full-duplex link between two endpoints, functionally equivalent to two
// OneWayLink objects tied together.
class SymmetricLink {
 public:
  SymmetricLink(Simulator* simulator,
                std::string name,
                UnconstrainedPortInterface* sink_a,
                UnconstrainedPortInterface* sink_b,
                QuicBandwidth bandwidth,
                QuicTime::Delta propagation_delay);
  SymmetricLink(Endpoint* endpoint_a,
                Endpoint* endpoint_b,
                QuicBandwidth bandwidth,
                QuicTime::Delta propagation_delay);
  SymmetricLink(const SymmetricLink&) = delete;
  SymmetricLink& operator=(const SymmetricLink&) = delete;

  inline QuicBandwidth bandwidth() { return a_to_b_link_.bandwidth(); }
  inline void set_bandwidth(QuicBandwidth new_bandwidth) {
    a_to_b_link_.set_bandwidth(new_bandwidth);
    b_to_a_link_.set_bandwidth(new_bandwidth);
  }

 private:
  OneWayLink a_to_b_link_;
  OneWayLink b_to_a_link_;
};

}  // namespace simulator
}  // namespace quic

#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_LINK_H_
