/*
 *  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_RX_INTERLEAVED_REASSEMBLY_STREAMS_H_
#define NET_DCSCTP_RX_INTERLEAVED_REASSEMBLY_STREAMS_H_

#include <cstdint>
#include <map>
#include <string>
#include <utility>

#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "net/dcsctp/common/sequence_numbers.h"
#include "net/dcsctp/packet/chunk/forward_tsn_common.h"
#include "net/dcsctp/packet/data.h"
#include "net/dcsctp/rx/reassembly_streams.h"

namespace dcsctp {

// Handles reassembly of incoming data when interleaved message sending is
// enabled on the association, i.e. when RFC8260 is in use.
class InterleavedReassemblyStreams : public ReassemblyStreams {
 public:
  InterleavedReassemblyStreams(absl::string_view log_prefix,
                               OnAssembledMessage on_assembled_message);

  int Add(UnwrappedTSN tsn, Data data) override;

  size_t HandleForwardTsn(
      UnwrappedTSN new_cumulative_ack_tsn,
      rtc::ArrayView<const AnyForwardTsnChunk::SkippedStream> skipped_streams)
      override;

  void ResetStreams(rtc::ArrayView<const StreamID> stream_ids) override;

  HandoverReadinessStatus GetHandoverReadiness() const override;
  void AddHandoverState(DcSctpSocketHandoverState& state) override;
  void RestoreFromState(const DcSctpSocketHandoverState& state) override;

 private:
  struct FullStreamId {
    const IsUnordered unordered;
    const StreamID stream_id;

    FullStreamId(IsUnordered unordered, StreamID stream_id)
        : unordered(unordered), stream_id(stream_id) {}

    friend bool operator<(FullStreamId a, FullStreamId b) {
      return a.unordered < b.unordered ||
             (!(a.unordered < b.unordered) && (a.stream_id < b.stream_id));
    }
  };

  class Stream {
   public:
    Stream(FullStreamId stream_id,
           InterleavedReassemblyStreams* parent,
           MID next_mid = MID(0))
        : stream_id_(stream_id),
          parent_(*parent),
          next_mid_(mid_unwrapper_.Unwrap(next_mid)) {}
    int Add(UnwrappedTSN tsn, Data data);
    size_t EraseTo(MID mid);
    void Reset() {
      mid_unwrapper_.Reset();
      next_mid_ = mid_unwrapper_.Unwrap(MID(0));
    }
    bool has_unassembled_chunks() const { return !chunks_by_mid_.empty(); }
    void AddHandoverState(DcSctpSocketHandoverState& state) const;

   private:
    using ChunkMap = std::map<FSN, std::pair<UnwrappedTSN, Data>>;

    // Try to assemble one message identified by `mid`.
    // Returns the number of bytes assembled if a message was assembled.
    size_t TryToAssembleMessage(UnwrappedMID mid);
    size_t AssembleMessage(const ChunkMap& tsn_chunks);
    // Try to assemble one or several messages in order from the stream.
    // Returns the number of bytes assembled if one or more messages were
    // assembled.
    size_t TryToAssembleMessages();

    const FullStreamId stream_id_;
    InterleavedReassemblyStreams& parent_;
    std::map<UnwrappedMID, ChunkMap> chunks_by_mid_;
    UnwrappedMID::Unwrapper mid_unwrapper_;
    UnwrappedMID next_mid_;
  };

  Stream& GetOrCreateStream(const FullStreamId& stream_id);

  const absl::string_view log_prefix_;

  // Callback for when a message has been assembled.
  const OnAssembledMessage on_assembled_message_;

  // All unordered and ordered streams, managing not-yet-assembled data.
  std::map<FullStreamId, Stream> streams_;
};

}  // namespace dcsctp

#endif  // NET_DCSCTP_RX_INTERLEAVED_REASSEMBLY_STREAMS_H_
