// 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 "quic/core/crypto/quic_random.h"
#include "quic/core/quic_bandwidth.h"
#include "quic/test_tools/simulator/actor.h"
#include "quic/test_tools/simulator/port.h"
#include "common/quiche_circular_deque.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;

  QuicBandwidth bandwidth() const { return bandwidth_; }
  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_;
  quiche::QuicheCircularDeque<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;

  QuicBandwidth bandwidth() { return a_to_b_link_.bandwidth(); }
  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_
