// Copyright 2013 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_PACKET_DROPPING_TEST_WRITER_H_
#define QUICHE_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_

#include <cstdint>
#include <list>
#include <memory>

#include "absl/base/attributes.h"
#include "quiche/quic/core/quic_alarm.h"
#include "quiche/quic/core/quic_alarm_factory.h"
#include "quiche/quic/core/quic_clock.h"
#include "quiche/quic/core/quic_connection.h"
#include "quiche/quic/core/quic_packet_writer_wrapper.h"
#include "quiche/quic/test_tools/quic_test_utils.h"
#include "quiche/common/platform/api/quiche_mutex.h"

namespace quic {
namespace test {

// Simulates a connection that drops packets a configured percentage of the time
// and has a blocked socket a configured percentage of the time.  Also provides
// the options to delay packets and reorder packets if delay is enabled.
class PacketDroppingTestWriter : public QuicPacketWriterWrapper {
 public:
  class Delegate {
   public:
    virtual ~Delegate() {}
    virtual void OnCanWrite() = 0;
  };

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

  ~PacketDroppingTestWriter() override;

  // Must be called before blocking, reordering or delaying (loss is OK). May be
  // called after connecting if the helper is not available before.
  // |on_can_write| will be triggered when fake-unblocking.
  void Initialize(QuicConnectionHelperInterface* helper,
                  QuicAlarmFactory* alarm_factory,
                  std::unique_ptr<Delegate> on_can_write);

  // QuicPacketWriter methods:
  WriteResult WritePacket(const char* buffer, size_t buf_len,
                          const QuicIpAddress& self_address,
                          const QuicSocketAddress& peer_address,
                          PerPacketOptions* options,
                          const QuicPacketWriterParams& params) override;

  bool IsWriteBlocked() const override;

  void SetWritable() override;

  QuicPacketBuffer GetNextWriteLocation(
      const QuicIpAddress& /*self_address*/,
      const QuicSocketAddress& /*peer_address*/) override {
    // If the wrapped writer supports zero-copy, disable it, because it is not
    // compatible with delayed writes in this class.
    return {nullptr, nullptr};
  }

  // Writes out any packet which should have been sent by now
  // to the contained writer and returns the time
  // for the next delayed packet to be written.
  QuicTime ReleaseOldPackets();

  // Sets |delay_alarm_| to fire at |new_deadline|.
  void SetDelayAlarm(QuicTime new_deadline);

  void OnCanWrite();

  // The percent of time a packet is simulated as being lost.
  // If |fake_packet_loss_percentage| is 100, then all packages are lost.
  // Otherwise actual percentage will be lower than
  // |fake_packet_loss_percentage|, because every dropped package is followed by
  // a minimum number of successfully written packets.
  void set_fake_packet_loss_percentage(int32_t fake_packet_loss_percentage) {
    quiche::QuicheWriterMutexLock lock(&config_mutex_);
    fake_packet_loss_percentage_ = fake_packet_loss_percentage;
  }

  // Once called, the next |passthrough_for_next_n_packets_| WritePacket() calls
  // will always send the packets immediately, without being affected by the
  // simulated error conditions.
  void set_passthrough_for_next_n_packets(
      uint32_t passthrough_for_next_n_packets) {
    quiche::QuicheWriterMutexLock lock(&config_mutex_);
    passthrough_for_next_n_packets_ = passthrough_for_next_n_packets;
  }

  // Simulate dropping the first n packets unconditionally.
  // Subsequent packets will be lost at fake_packet_loss_percentage_ if set.
  void set_fake_drop_first_n_packets(int32_t fake_drop_first_n_packets) {
    quiche::QuicheWriterMutexLock lock(&config_mutex_);
    fake_drop_first_n_packets_ = fake_drop_first_n_packets;
  }

  // The percent of time WritePacket will block and set WriteResult's status
  // to WRITE_STATUS_BLOCKED.
  void set_fake_blocked_socket_percentage(
      int32_t fake_blocked_socket_percentage) {
    QUICHE_DCHECK(clock_);
    quiche::QuicheWriterMutexLock lock(&config_mutex_);
    fake_blocked_socket_percentage_ = fake_blocked_socket_percentage;
  }

  // The percent of time a packet is simulated as being reordered.
  void set_fake_reorder_percentage(int32_t fake_packet_reorder_percentage) {
    QUICHE_DCHECK(clock_);
    quiche::QuicheWriterMutexLock lock(&config_mutex_);
    QUICHE_DCHECK(!fake_packet_delay_.IsZero());
    fake_packet_reorder_percentage_ = fake_packet_reorder_percentage;
  }

  // The delay before writing this packet.
  void set_fake_packet_delay(QuicTime::Delta fake_packet_delay) {
    QUICHE_DCHECK(clock_);
    quiche::QuicheWriterMutexLock lock(&config_mutex_);
    fake_packet_delay_ = fake_packet_delay;
  }

  // The maximum bandwidth and buffer size of the connection.  When these are
  // set, packets will be delayed until a connection with that bandwidth would
  // transmit it.  Once the |buffer_size| is reached, all new packets are
  // dropped.
  void set_max_bandwidth_and_buffer_size(QuicBandwidth fake_bandwidth,
                                         QuicByteCount buffer_size) {
    QUICHE_DCHECK(clock_);
    quiche::QuicheWriterMutexLock lock(&config_mutex_);
    fake_bandwidth_ = fake_bandwidth;
    buffer_size_ = buffer_size;
  }

  // Useful for reproducing very flaky issues.
  ABSL_ATTRIBUTE_UNUSED void set_seed(uint64_t seed) {
    simple_random_.set_seed(seed);
  }

 private:
  // Writes out the next packet to the contained writer and returns the time
  // for the next delayed packet to be written.
  QuicTime ReleaseNextPacket();

  // A single packet which will be sent at the supplied send_time.
  struct DelayedWrite {
   public:
    DelayedWrite(const char* buffer, size_t buf_len,
                 const QuicIpAddress& self_address,
                 const QuicSocketAddress& peer_address,
                 std::unique_ptr<PerPacketOptions> options,
                 const QuicPacketWriterParams& params, QuicTime send_time);
    DelayedWrite(const DelayedWrite&) = delete;
    DelayedWrite(DelayedWrite&&) = default;
    DelayedWrite& operator=(const DelayedWrite&) = delete;
    DelayedWrite& operator=(DelayedWrite&&) = default;
    ~DelayedWrite();

    std::string buffer;
    QuicIpAddress self_address;
    QuicSocketAddress peer_address;
    std::unique_ptr<PerPacketOptions> options;
    QuicPacketWriterParams params;
    QuicTime send_time;
  };

  using DelayedPacketList = std::list<DelayedWrite>;

  const QuicClock* clock_;
  std::unique_ptr<QuicAlarm> write_unblocked_alarm_;
  std::unique_ptr<QuicAlarm> delay_alarm_;
  std::unique_ptr<Delegate> on_can_write_;
  SimpleRandom simple_random_;
  // Stored packets delayed by fake packet delay or bandwidth restrictions.
  DelayedPacketList delayed_packets_;
  QuicByteCount cur_buffer_size_;
  uint64_t num_calls_to_write_;
  uint32_t passthrough_for_next_n_packets_ QUICHE_GUARDED_BY(config_mutex_);
  int32_t num_consecutive_succesful_writes_;

  quiche::QuicheMutex config_mutex_;
  int32_t fake_packet_loss_percentage_ QUICHE_GUARDED_BY(config_mutex_);
  int32_t fake_drop_first_n_packets_ QUICHE_GUARDED_BY(config_mutex_);
  int32_t fake_blocked_socket_percentage_ QUICHE_GUARDED_BY(config_mutex_);
  int32_t fake_packet_reorder_percentage_ QUICHE_GUARDED_BY(config_mutex_);
  QuicTime::Delta fake_packet_delay_ QUICHE_GUARDED_BY(config_mutex_);
  QuicBandwidth fake_bandwidth_ QUICHE_GUARDED_BY(config_mutex_);
  QuicByteCount buffer_size_ QUICHE_GUARDED_BY(config_mutex_);
};

}  // namespace test
}  // namespace quic

#endif  // QUICHE_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
