/*
 *  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_PACKET_TLV_TRAIT_H_
#define NET_DCSCTP_PACKET_TLV_TRAIT_H_

#include <stdint.h>
#include <string.h>

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <string>
#include <vector>

#include "absl/types/optional.h"
#include "api/array_view.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"

namespace dcsctp {
namespace tlv_trait_impl {
// Logging functions, only to be used by TLVTrait, which is a templated class.
void ReportInvalidSize(size_t actual_size, size_t expected_size);
void ReportInvalidType(int actual_type, int expected_type);
void ReportInvalidFixedLengthField(size_t value, size_t expected);
void ReportInvalidVariableLengthField(size_t value, size_t available);
void ReportInvalidPadding(size_t padding_bytes);
void ReportInvalidLengthMultiple(size_t length, size_t alignment);
}  // namespace tlv_trait_impl

// Various entities in SCTP are padded data blocks, with a type and length
// field at fixed offsets, all stored in a 4-byte header.
//
// See e.g. https://tools.ietf.org/html/rfc4960#section-3.2 and
// https://tools.ietf.org/html/rfc4960#section-3.2.1
//
// These are helper classes for writing and parsing that data, which in SCTP is
// called Type-Length-Value, or TLV.
//
// This templated class is configurable - a struct passed in as template
// parameter with the following expected members:
//   * kType                    - The type field's value
//   * kTypeSizeInBytes         - The type field's width in bytes.
//                                Either 1 or 2.
//   * kHeaderSize              - The fixed size header
//   * kVariableLengthAlignment - The size alignment on the variable data. Set
//                                to zero (0) if no variable data is used.
//
// This class is to be used as a trait
// (https://en.wikipedia.org/wiki/Trait_(computer_programming)) that adds a few
// public and protected members and which a class inherits from when it
// represents a type-length-value object.
template <typename Config>
class TLVTrait {
 private:
  static constexpr size_t kTlvHeaderSize = 4;

 protected:
  static constexpr size_t kHeaderSize = Config::kHeaderSize;

  static_assert(Config::kTypeSizeInBytes == 1 || Config::kTypeSizeInBytes == 2,
                "kTypeSizeInBytes must be 1 or 2");
  static_assert(Config::kHeaderSize >= kTlvHeaderSize,
                "HeaderSize must be >= 4 bytes");
  static_assert((Config::kHeaderSize % 4 == 0),
                "kHeaderSize must be an even multiple of 4 bytes");
  static_assert((Config::kVariableLengthAlignment == 0 ||
                 Config::kVariableLengthAlignment == 1 ||
                 Config::kVariableLengthAlignment == 2 ||
                 Config::kVariableLengthAlignment == 4 ||
                 Config::kVariableLengthAlignment == 8),
                "kVariableLengthAlignment must be an allowed value");

  // Validates the data with regards to size, alignment and type.
  // If valid, returns a bounded buffer.
  static absl::optional<BoundedByteReader<Config::kHeaderSize>> ParseTLV(
      rtc::ArrayView<const uint8_t> data) {
    if (data.size() < Config::kHeaderSize) {
      tlv_trait_impl::ReportInvalidSize(data.size(), Config::kHeaderSize);
      return absl::nullopt;
    }
    BoundedByteReader<kTlvHeaderSize> tlv_header(data);

    const int type = (Config::kTypeSizeInBytes == 1)
                         ? tlv_header.template Load8<0>()
                         : tlv_header.template Load16<0>();

    if (type != Config::kType) {
      tlv_trait_impl::ReportInvalidType(type, Config::kType);
      return absl::nullopt;
    }
    const uint16_t length = tlv_header.template Load16<2>();
    if (Config::kVariableLengthAlignment == 0) {
      // Don't expect any variable length data at all.
      if (length != Config::kHeaderSize || data.size() != Config::kHeaderSize) {
        tlv_trait_impl::ReportInvalidFixedLengthField(length,
                                                      Config::kHeaderSize);
        return absl::nullopt;
      }
    } else {
      // Expect variable length data - verify its size alignment.
      if (length > data.size() || length < Config::kHeaderSize) {
        tlv_trait_impl::ReportInvalidVariableLengthField(length, data.size());
        return absl::nullopt;
      }
      const size_t padding = data.size() - length;
      if (padding > 3) {
        // https://tools.ietf.org/html/rfc4960#section-3.2
        // "This padding MUST NOT be more than 3 bytes in total"
        tlv_trait_impl::ReportInvalidPadding(padding);
        return absl::nullopt;
      }
      if (!ValidateLengthAlignment(length, Config::kVariableLengthAlignment)) {
        tlv_trait_impl::ReportInvalidLengthMultiple(
            length, Config::kVariableLengthAlignment);
        return absl::nullopt;
      }
    }
    return BoundedByteReader<Config::kHeaderSize>(data.subview(0, length));
  }

  // Allocates space for data with a static header size, as defined by
  // `Config::kHeaderSize` and a variable footer, as defined by `variable_size`
  // (which may be 0) and writes the type and length in the header.
  static BoundedByteWriter<Config::kHeaderSize> AllocateTLV(
      std::vector<uint8_t>& out,
      size_t variable_size = 0) {
    const size_t offset = out.size();
    const size_t size = Config::kHeaderSize + variable_size;
    out.resize(offset + size);

    BoundedByteWriter<kTlvHeaderSize> tlv_header(
        rtc::ArrayView<uint8_t>(out.data() + offset, kTlvHeaderSize));
    if (Config::kTypeSizeInBytes == 1) {
      tlv_header.template Store8<0>(static_cast<uint8_t>(Config::kType));
    } else {
      tlv_header.template Store16<0>(Config::kType);
    }
    tlv_header.template Store16<2>(size);

    return BoundedByteWriter<Config::kHeaderSize>(
        rtc::ArrayView<uint8_t>(out.data() + offset, size));
  }

 private:
  static bool ValidateLengthAlignment(uint16_t length, size_t alignment) {
    // This is to avoid MSVC believing there could be a "mod by zero", when it
    // certainly can't.
    if (alignment == 0) {
      return true;
    }
    return (length % alignment) == 0;
  }
};

}  // namespace dcsctp

#endif  // NET_DCSCTP_PACKET_TLV_TRAIT_H_
