/*
 *  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/init_ack_chunk.h"

#include <stdint.h>

#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/tlv_trait.h"
#include "rtc_base/strings/string_format.h"

namespace dcsctp {

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

//   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 = 2    |  Chunk Flags  |      Chunk Length             |
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  |                         Initiate Tag                          |
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  |              Advertised Receiver Window Credit                |
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  |  Number of Outbound Streams   |  Number of Inbound Streams    |
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  |                          Initial TSN                          |
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  \                                                               \
//  /              Optional/Variable-Length Parameters              /
//  \                                                               \
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int InitAckChunk::kType;

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

  VerificationTag initiate_tag(reader->Load32<4>());
  uint32_t a_rwnd = reader->Load32<8>();
  uint16_t nbr_outbound_streams = reader->Load16<12>();
  uint16_t nbr_inbound_streams = reader->Load16<14>();
  TSN initial_tsn(reader->Load32<16>());
  std::optional<Parameters> parameters =
      Parameters::Parse(reader->variable_data());
  if (!parameters.has_value()) {
    return std::nullopt;
  }
  return InitAckChunk(initiate_tag, a_rwnd, nbr_outbound_streams,
                      nbr_inbound_streams, initial_tsn, *std::move(parameters));
}

void InitAckChunk::SerializeTo(std::vector<uint8_t>& out) const {
  rtc::ArrayView<const uint8_t> parameters = parameters_.data();
  BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, parameters.size());

  writer.Store32<4>(*initiate_tag_);
  writer.Store32<8>(a_rwnd_);
  writer.Store16<12>(nbr_outbound_streams_);
  writer.Store16<14>(nbr_inbound_streams_);
  writer.Store32<16>(*initial_tsn_);
  writer.CopyToVariableData(parameters);
}

std::string InitAckChunk::ToString() const {
  return rtc::StringFormat("INIT_ACK, initiate_tag=0x%0x, initial_tsn=%u",
                           *initiate_tag(), *initial_tsn());
}
}  // namespace dcsctp
