/*
 *  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.
 */
#include "net/dcsctp/packet/chunk/sack_chunk.h"

#include <stddef.h>

#include <cstdint>
#include <string>
#include <type_traits>
#include <vector>

#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/common/str_join.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/logging.h"
#include "rtc_base/strings/string_builder.h"

namespace dcsctp {

// https://tools.ietf.org/html/rfc4960#section-3.3.4

//   0                   1                   2                   3
//   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  |   Type = 3    |Chunk  Flags   |      Chunk Length             |
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  |                      Cumulative TSN Ack                       |
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  |          Advertised Receiver Window Credit (a_rwnd)           |
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  | Number of Gap Ack Blocks = N  |  Number of Duplicate TSNs = X |
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  |  Gap Ack Block #1 Start       |   Gap Ack Block #1 End        |
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  /                                                               /
//  \                              ...                              \
//  /                                                               /
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  |   Gap Ack Block #N Start      |  Gap Ack Block #N End         |
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  |                       Duplicate TSN 1                         |
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  /                                                               /
//  \                              ...                              \
//  /                                                               /
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  |                       Duplicate TSN X                         |
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int SackChunk::kType;

absl::optional<SackChunk> SackChunk::Parse(rtc::ArrayView<const uint8_t> data) {
  absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
  if (!reader.has_value()) {
    return absl::nullopt;
  }

  TSN tsn_ack(reader->Load32<4>());
  uint32_t a_rwnd = reader->Load32<8>();
  uint16_t nbr_of_gap_blocks = reader->Load16<12>();
  uint16_t nbr_of_dup_tsns = reader->Load16<14>();

  if (reader->variable_data_size() != nbr_of_gap_blocks * kGapAckBlockSize +
                                          nbr_of_dup_tsns * kDupTsnBlockSize) {
    RTC_DLOG(LS_WARNING) << "Invalid number of gap blocks or duplicate TSNs";
    return absl::nullopt;
  }

  std::vector<GapAckBlock> gap_ack_blocks;
  gap_ack_blocks.reserve(nbr_of_gap_blocks);
  size_t offset = 0;
  for (int i = 0; i < nbr_of_gap_blocks; ++i) {
    BoundedByteReader<kGapAckBlockSize> sub_reader =
        reader->sub_reader<kGapAckBlockSize>(offset);

    uint16_t start = sub_reader.Load16<0>();
    uint16_t end = sub_reader.Load16<2>();
    gap_ack_blocks.emplace_back(start, end);
    offset += kGapAckBlockSize;
  }

  std::vector<TSN> duplicate_tsns;
  duplicate_tsns.reserve(nbr_of_gap_blocks);
  for (int i = 0; i < nbr_of_dup_tsns; ++i) {
    BoundedByteReader<kDupTsnBlockSize> sub_reader =
        reader->sub_reader<kDupTsnBlockSize>(offset);

    duplicate_tsns.push_back(TSN(sub_reader.Load32<0>()));
    offset += kDupTsnBlockSize;
  }
  RTC_DCHECK(offset == reader->variable_data_size());

  return SackChunk(tsn_ack, a_rwnd, gap_ack_blocks, duplicate_tsns);
}

void SackChunk::SerializeTo(std::vector<uint8_t>& out) const {
  int nbr_of_gap_blocks = gap_ack_blocks_.size();
  int nbr_of_dup_tsns = duplicate_tsns_.size();
  size_t variable_size =
      nbr_of_gap_blocks * kGapAckBlockSize + nbr_of_dup_tsns * kDupTsnBlockSize;
  BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, variable_size);

  writer.Store32<4>(*cumulative_tsn_ack_);
  writer.Store32<8>(a_rwnd_);
  writer.Store16<12>(nbr_of_gap_blocks);
  writer.Store16<14>(nbr_of_dup_tsns);

  size_t offset = 0;
  for (int i = 0; i < nbr_of_gap_blocks; ++i) {
    BoundedByteWriter<kGapAckBlockSize> sub_writer =
        writer.sub_writer<kGapAckBlockSize>(offset);

    sub_writer.Store16<0>(gap_ack_blocks_[i].start);
    sub_writer.Store16<2>(gap_ack_blocks_[i].end);
    offset += kGapAckBlockSize;
  }

  for (int i = 0; i < nbr_of_dup_tsns; ++i) {
    BoundedByteWriter<kDupTsnBlockSize> sub_writer =
        writer.sub_writer<kDupTsnBlockSize>(offset);

    sub_writer.Store32<0>(*duplicate_tsns_[i]);
    offset += kDupTsnBlockSize;
  }

  RTC_DCHECK(offset == variable_size);
}

std::string SackChunk::ToString() const {
  rtc::StringBuilder sb;
  sb << "SACK, cum_ack_tsn=" << *cumulative_tsn_ack()
     << ", a_rwnd=" << a_rwnd();
  for (const GapAckBlock& gap : gap_ack_blocks_) {
    uint32_t first = *cumulative_tsn_ack_ + gap.start;
    uint32_t last = *cumulative_tsn_ack_ + gap.end;
    sb << ", gap=" << first << "--" << last;
  }
  if (!duplicate_tsns_.empty()) {
    sb << ", dup_tsns="
       << StrJoin(duplicate_tsns(), ",",
                  [](rtc::StringBuilder& sb, TSN tsn) { sb << *tsn; });
  }

  return sb.Release();
}

}  // namespace dcsctp
