/*
 *  Copyright (c) 2021 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 NET_DCSCTP_TX_OUTSTANDING_DATA_H_
#define NET_DCSCTP_TX_OUTSTANDING_DATA_H_

#include <map>
#include <set>
#include <utility>
#include <vector>

#include "absl/types/optional.h"
#include "net/dcsctp/common/sequence_numbers.h"
#include "net/dcsctp/packet/chunk/forward_tsn_chunk.h"
#include "net/dcsctp/packet/chunk/iforward_tsn_chunk.h"
#include "net/dcsctp/packet/chunk/sack_chunk.h"
#include "net/dcsctp/packet/data.h"

namespace dcsctp {

// This class keeps track of outstanding data chunks (sent, not yet acked) and
// handles acking, nacking, rescheduling and abandoning.
class OutstandingData {
 public:
  // State for DATA chunks (message fragments) in the queue - used in tests.
  enum class State {
    // The chunk has been sent but not received yet (from the sender's point of
    // view, as no SACK has been received yet that reference this chunk).
    kInFlight,
    // A SACK has been received which explicitly marked this chunk as missing -
    // it's now NACKED and may be retransmitted if NACKED enough times.
    kNacked,
    // A chunk that will be retransmitted when possible.
    kToBeRetransmitted,
    // A SACK has been received which explicitly marked this chunk as received.
    kAcked,
    // A chunk whose message has expired or has been retransmitted too many
    // times (RFC3758). It will not be retransmitted anymore.
    kAbandoned,
  };

  // Contains variables scoped to a processing of an incoming SACK.
  struct AckInfo {
    explicit AckInfo(UnwrappedTSN cumulative_tsn_ack)
        : highest_tsn_acked(cumulative_tsn_ack) {}

    // Bytes acked by increasing cumulative_tsn_ack and gap_ack_blocks.
    size_t bytes_acked = 0;

    // Indicates if this SACK indicates that packet loss has occurred. Just
    // because a packet is missing in the SACK doesn't necessarily mean that
    // there is packet loss as that packet might be in-flight and received
    // out-of-order. But when it has been reported missing consecutive times, it
    // will eventually be considered "lost" and this will be set.
    bool has_packet_loss = false;

    // Highest TSN Newly Acknowledged, an SCTP variable.
    UnwrappedTSN highest_tsn_acked;
  };

  OutstandingData(
      size_t data_chunk_header_size,
      UnwrappedTSN next_tsn,
      UnwrappedTSN last_cumulative_tsn_ack,
      std::function<bool(IsUnordered, StreamID, MID)> discard_from_send_queue)
      : data_chunk_header_size_(data_chunk_header_size),
        next_tsn_(next_tsn),
        last_cumulative_tsn_ack_(last_cumulative_tsn_ack),
        discard_from_send_queue_(std::move(discard_from_send_queue)) {}

  AckInfo HandleSack(
      UnwrappedTSN cumulative_tsn_ack,
      rtc::ArrayView<const SackChunk::GapAckBlock> gap_ack_blocks,
      bool is_in_fast_recovery);

  // Returns as many of the chunks that are eligible for fast retransmissions
  // and that would fit in a single packet of `max_size`. The eligible chunks
  // that didn't fit will be marked for (normal) retransmission and will not be
  // returned if this method is called again.
  std::vector<std::pair<TSN, Data>> GetChunksToBeFastRetransmitted(
      size_t max_size);

  // Given `max_size` of space left in a packet, which chunks can be added to
  // it?
  std::vector<std::pair<TSN, Data>> GetChunksToBeRetransmitted(size_t max_size);

  size_t outstanding_bytes() const { return outstanding_bytes_; }

  // Returns the number of DATA chunks that are in-flight.
  size_t outstanding_items() const { return outstanding_items_; }

  // Given the current time `now_ms`, expire and abandon outstanding (sent at
  // least once) chunks that have a limited lifetime.
  void ExpireOutstandingChunks(TimeMs now);

  bool empty() const { return outstanding_data_.empty(); }

  bool has_data_to_be_fast_retransmitted() const {
    return !to_be_fast_retransmitted_.empty();
  }

  bool has_data_to_be_retransmitted() const {
    return !to_be_retransmitted_.empty() || !to_be_fast_retransmitted_.empty();
  }

  UnwrappedTSN last_cumulative_tsn_ack() const {
    return last_cumulative_tsn_ack_;
  }

  UnwrappedTSN next_tsn() const { return next_tsn_; }

  UnwrappedTSN highest_outstanding_tsn() const;

  // Schedules `data` to be sent, with the provided partial reliability
  // parameters. Returns the TSN if the item was actually added and scheduled to
  // be sent, and absl::nullopt if it shouldn't be sent.
  absl::optional<UnwrappedTSN> Insert(const Data& data,
                                      MaxRetransmits max_retransmissions,
                                      TimeMs time_sent,
                                      TimeMs expires_at);

  // Nacks all outstanding data.
  void NackAll();

  // Creates a FORWARD-TSN chunk.
  ForwardTsnChunk CreateForwardTsn() const;

  // Creates an I-FORWARD-TSN chunk.
  IForwardTsnChunk CreateIForwardTsn() const;

  // Given the current time and a TSN, it returns the measured RTT between when
  // the chunk was sent and now. It takes into acccount Karn's algorithm, so if
  // the chunk has ever been retransmitted, it will return absl::nullopt.
  absl::optional<DurationMs> MeasureRTT(TimeMs now, UnwrappedTSN tsn) const;

  // Returns the internal state of all queued chunks. This is only used in
  // unit-tests.
  std::vector<std::pair<TSN, State>> GetChunkStatesForTesting() const;

  // Returns true if the next chunk that is not acked by the peer has been
  // abandoned, which means that a FORWARD-TSN should be sent.
  bool ShouldSendForwardTsn() const;

  // Sets the next TSN to be used. This is used in handover.
  void ResetSequenceNumbers(UnwrappedTSN next_tsn,
                            UnwrappedTSN last_cumulative_tsn);

 private:
  // A fragmented message's DATA chunk while in the retransmission queue, and
  // its associated metadata.
  class Item {
   public:
    enum class NackAction {
      kNothing,
      kRetransmit,
      kAbandon,
    };

    explicit Item(Data data,
                  MaxRetransmits max_retransmissions,
                  TimeMs time_sent,
                  TimeMs expires_at)
        : max_retransmissions_(max_retransmissions),
          time_sent_(time_sent),
          expires_at_(expires_at),
          data_(std::move(data)) {}

    TimeMs time_sent() const { return time_sent_; }

    const Data& data() const { return data_; }

    // Acks an item.
    void Ack();

    // Nacks an item. If it has been nacked enough times, or if `retransmit_now`
    // is set, it might be marked for retransmission. If the item has reached
    // its max retransmission value, it will instead be abandoned. The action
    // performed is indicated as return value.
    NackAction Nack(bool retransmit_now);

    // Prepares the item to be retransmitted. Sets it as outstanding and
    // clears all nack counters.
    void MarkAsRetransmitted();

    // Marks this item as abandoned.
    void Abandon();

    bool is_outstanding() const { return ack_state_ == AckState::kUnacked; }
    bool is_acked() const { return ack_state_ == AckState::kAcked; }
    bool is_nacked() const { return ack_state_ == AckState::kNacked; }
    bool is_abandoned() const { return lifecycle_ == Lifecycle::kAbandoned; }

    // Indicates if this chunk should be retransmitted.
    bool should_be_retransmitted() const {
      return lifecycle_ == Lifecycle::kToBeRetransmitted;
    }
    // Indicates if this chunk has ever been retransmitted.
    bool has_been_retransmitted() const { return num_retransmissions_ > 0; }

    // Given the current time, and the current state of this DATA chunk, it will
    // indicate if it has expired (SCTP Partial Reliability Extension).
    bool has_expired(TimeMs now) const;

   private:
    enum class Lifecycle {
      // The chunk is alive (sent, received, etc)
      kActive,
      // The chunk is scheduled to be retransmitted, and will then transition to
      // become active.
      kToBeRetransmitted,
      // The chunk has been abandoned. This is a terminal state.
      kAbandoned
    };
    enum class AckState {
      // The chunk is in-flight.
      kUnacked,
      // The chunk has been received and acknowledged.
      kAcked,
      // The chunk has been nacked and is possibly lost.
      kNacked
    };
    // Indicates the life cycle status of this chunk.
    Lifecycle lifecycle_ = Lifecycle::kActive;
    // Indicates the presence of this chunk, if it's in flight (Unacked), has
    // been received (Acked) or is possibly lost (Nacked).
    AckState ack_state_ = AckState::kUnacked;

    // The number of times the DATA chunk has been nacked (by having received a
    // SACK which doesn't include it). Will be cleared on retransmissions.
    uint8_t nack_count_ = 0;
    // The number of times the DATA chunk has been retransmitted.
    uint16_t num_retransmissions_ = 0;
    // If the message was sent with a maximum number of retransmissions, this is
    // set to that number. The value zero (0) means that it will never be
    // retransmitted.
    const MaxRetransmits max_retransmissions_;
    // When the packet was sent, and placed in this queue.
    const TimeMs time_sent_;
    // At this exact millisecond, the item is considered expired. If the message
    // is not to be expired, this is set to the infinite future.
    const TimeMs expires_at_;
    // The actual data to send/retransmit.
    Data data_;
  };

  // Returns how large a chunk will be, serialized, carrying the data
  size_t GetSerializedChunkSize(const Data& data) const;

  // Given a `cumulative_tsn_ack` from an incoming SACK, will remove those items
  // in the retransmission queue up until this value and will update `ack_info`
  // by setting `bytes_acked_by_cumulative_tsn_ack`.
  void RemoveAcked(UnwrappedTSN cumulative_tsn_ack, AckInfo& ack_info);

  // Will mark the chunks covered by the `gap_ack_blocks` from an incoming SACK
  // as "acked" and update `ack_info` by adding new TSNs to `added_tsns`.
  void AckGapBlocks(UnwrappedTSN cumulative_tsn_ack,
                    rtc::ArrayView<const SackChunk::GapAckBlock> gap_ack_blocks,
                    AckInfo& ack_info);

  // Mark chunks reported as "missing", as "nacked" or "to be retransmitted"
  // depending how many times this has happened. Only packets up until
  // `ack_info.highest_tsn_acked` (highest TSN newly acknowledged) are
  // nacked/retransmitted. The method will set `ack_info.has_packet_loss`.
  void NackBetweenAckBlocks(
      UnwrappedTSN cumulative_tsn_ack,
      rtc::ArrayView<const SackChunk::GapAckBlock> gap_ack_blocks,
      bool is_in_fast_recovery,
      OutstandingData::AckInfo& ack_info);

  // Process the acknowledgement of the chunk referenced by `iter` and updates
  // state in `ack_info` and the object's state.
  void AckChunk(AckInfo& ack_info, std::map<UnwrappedTSN, Item>::iterator iter);

  // Helper method to process an incoming nack of an item and perform the
  // correct operations given the action indicated when nacking an item (e.g.
  // retransmitting or abandoning). The return value indicate if an action was
  // performed, meaning that packet loss was detected and acted upon. If
  // `do_fast_retransmit` is set and if the item has been nacked sufficiently
  // many times so that it should be retransmitted, this will schedule it to be
  // "fast retransmitted". This is only done just before going into fast
  // recovery.
  bool NackItem(UnwrappedTSN tsn,
                Item& item,
                bool retransmit_now,
                bool do_fast_retransmit);

  // Given that a message fragment, `item` has been abandoned, abandon all other
  // fragments that share the same message - both never-before-sent fragments
  // that are still in the SendQueue and outstanding chunks.
  void AbandonAllFor(const OutstandingData::Item& item);

  std::vector<std::pair<TSN, Data>> ExtractChunksThatCanFit(
      std::set<UnwrappedTSN>& chunks,
      size_t max_size);

  bool IsConsistent() const;

  // The size of the data chunk (DATA/I-DATA) header that is used.
  const size_t data_chunk_header_size_;
  // Next TSN to used.
  UnwrappedTSN next_tsn_;
  // The last cumulative TSN ack number.
  UnwrappedTSN last_cumulative_tsn_ack_;
  // Callback when to discard items from the send queue.
  std::function<bool(IsUnordered, StreamID, MID)> discard_from_send_queue_;

  std::map<UnwrappedTSN, Item> outstanding_data_;
  // The number of bytes that are in-flight (sent but not yet acked or nacked).
  size_t outstanding_bytes_ = 0;
  // The number of DATA chunks that are in-flight (sent but not yet acked or
  // nacked).
  size_t outstanding_items_ = 0;
  // Data chunks that are eligible for fast retransmission.
  std::set<UnwrappedTSN> to_be_fast_retransmitted_;
  // Data chunks that are to be retransmitted.
  std::set<UnwrappedTSN> to_be_retransmitted_;
};
}  // namespace dcsctp
#endif  // NET_DCSCTP_TX_OUTSTANDING_DATA_H_
