/*
 *  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 <optional>
#include <string>
#include <vector>

#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 std::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 std::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 std::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 std::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 std::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 std::nullopt;
      }
      if (!ValidateLengthAlignment(length, Config::kVariableLengthAlignment)) {
        tlv_trait_impl::ReportInvalidLengthMultiple(
            length, Config::kVariableLengthAlignment);
        return std::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_
