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

#include <stddef.h>
#include <stdint.h>

#include <optional>
#include <string>
#include <type_traits>
#include <vector>

#include "absl/strings/string_view.h"
#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/tlv_trait.h"
#include "rtc_base/logging.h"
#include "rtc_base/strings/string_builder.h"

namespace dcsctp {

// https://tools.ietf.org/html/rfc6525#section-4.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
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  |     Parameter Type = 16       |      Parameter Length         |
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  |         Re-configuration Response Sequence Number             |
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  |                            Result                             |
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  |                   Sender's Next TSN (optional)                |
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  |                  Receiver's Next TSN (optional)               |
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
constexpr int ReconfigurationResponseParameter::kType;

absl::string_view ToString(ReconfigurationResponseParameter::Result result) {
  switch (result) {
    case ReconfigurationResponseParameter::Result::kSuccessNothingToDo:
      return "Success: nothing to do";
    case ReconfigurationResponseParameter::Result::kSuccessPerformed:
      return "Success: performed";
    case ReconfigurationResponseParameter::Result::kDenied:
      return "Denied";
    case ReconfigurationResponseParameter::Result::kErrorWrongSSN:
      return "Error: wrong ssn";
    case ReconfigurationResponseParameter::Result::
        kErrorRequestAlreadyInProgress:
      return "Error: request already in progress";
    case ReconfigurationResponseParameter::Result::kErrorBadSequenceNumber:
      return "Error: bad sequence number";
    case ReconfigurationResponseParameter::Result::kInProgress:
      return "In progress";
  }
}

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

  ReconfigRequestSN response_sequence_number(reader->Load32<4>());
  Result result;
  uint32_t result_nbr = reader->Load32<8>();
  switch (result_nbr) {
    case 0:
      result = ReconfigurationResponseParameter::Result::kSuccessNothingToDo;
      break;
    case 1:
      result = ReconfigurationResponseParameter::Result::kSuccessPerformed;
      break;
    case 2:
      result = ReconfigurationResponseParameter::Result::kDenied;
      break;
    case 3:
      result = ReconfigurationResponseParameter::Result::kErrorWrongSSN;
      break;
    case 4:
      result = ReconfigurationResponseParameter::Result::
          kErrorRequestAlreadyInProgress;
      break;
    case 5:
      result =
          ReconfigurationResponseParameter::Result::kErrorBadSequenceNumber;
      break;
    case 6:
      result = ReconfigurationResponseParameter::Result::kInProgress;
      break;
    default:
      RTC_DLOG(LS_WARNING) << "Invalid reconfig response result: "
                           << result_nbr;
      return std::nullopt;
  }

  if (reader->variable_data().empty()) {
    return ReconfigurationResponseParameter(response_sequence_number, result);
  } else if (reader->variable_data_size() != kNextTsnHeaderSize) {
    RTC_DLOG(LS_WARNING) << "Invalid parameter size";
    return std::nullopt;
  }

  BoundedByteReader<kNextTsnHeaderSize> sub_reader =
      reader->sub_reader<kNextTsnHeaderSize>(0);

  TSN sender_next_tsn(sub_reader.Load32<0>());
  TSN receiver_next_tsn(sub_reader.Load32<4>());

  return ReconfigurationResponseParameter(response_sequence_number, result,
                                          sender_next_tsn, receiver_next_tsn);
}

void ReconfigurationResponseParameter::SerializeTo(
    std::vector<uint8_t>& out) const {
  size_t variable_size =
      (sender_next_tsn().has_value() ? kNextTsnHeaderSize : 0);
  BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, variable_size);

  writer.Store32<4>(*response_sequence_number_);
  uint32_t result_nbr =
      static_cast<std::underlying_type<Result>::type>(result_);
  writer.Store32<8>(result_nbr);

  if (sender_next_tsn().has_value()) {
    BoundedByteWriter<kNextTsnHeaderSize> sub_writer =
        writer.sub_writer<kNextTsnHeaderSize>(0);

    sub_writer.Store32<0>(sender_next_tsn_.has_value() ? **sender_next_tsn_
                                                       : 0);
    sub_writer.Store32<4>(receiver_next_tsn_.has_value() ? **receiver_next_tsn_
                                                         : 0);
  }
}

std::string ReconfigurationResponseParameter::ToString() const {
  rtc::StringBuilder sb;
  sb << "Re-configuration Response, resp_seq_nbr="
     << *response_sequence_number();
  return sb.Release();
}
}  // namespace dcsctp
