// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_SDP_DATA_ELEMENT_H_
#define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_SDP_DATA_ELEMENT_H_

#include <vector>

#include "src/connectivity/bluetooth/core/bt-host/common/byte_buffer.h"
#include "src/connectivity/bluetooth/core/bt-host/common/uuid.h"

namespace bt {
namespace sdp {

// See v5.0, Vol 3, Part B, Sec 3.1.
// Each Data element has a header and a data field.
// The header field contains a type descriptor and a size descriptor.
// The header field is of variable length, which is determined by the size
// descriptor.
//
// DataElements all start as the Null type, and then can be set to any type.
// Examples:
// DataElement elem;  // A null type
// uint32_t seymour = 0xFEED;
// elem.Set(seymour);
// ZX_DEBUG_ASSERT(elem.type() == DataElement::Type::kUnsignedInt);
// ZX_DEBUG_ASSERT(elem.Get<uint32_t>());
// ZX_DEBUG_ASSERT(*elem.Get<uint32_t>() == seymour);
//
// std::vector<DataElement> service_class_ids;
// DataElement uuid;
// uuid.Set(UUID(sdp::ServiceClass::kAudioSource));
// service_class_ids.emplace_back(std::move(uuid));
// elem.Set(service_class_ids);
// ZX_DEBUG_ASSERT(e.type() == DataElement::Type::kSeqeuence);
// ZX_DEBUG_ASSERT(!e.Get<uint32_t>());
class DataElement {
 public:
  // Type Descriptors. Only the top 5 bits are used, see kTypeMask
  // v5.0, Vol 3, Part B, Sec 3.2.
  enum class Type : uint8_t {
    kNull = (0 << 3),
    kUnsignedInt = (1 << 3),
    kSignedInt = (2 << 3),
    kUuid = (3 << 3),
    kString = (4 << 3),
    kBoolean = (5 << 3),
    kSequence = (6 << 3),
    kAlternative = (7 << 3),
    kUrl = (8 << 3),
  };
  constexpr static uint8_t kTypeMask = 0xF8;

  // Size Descriptor describing the size of the data following.
  // Only three bits are used.
  // For 0-4, the size is 2^(value) except in the case of kNull, in which
  // case the size is 0.
  // otherwise, the size is described in 2^(5-value) extra bytes following.
  // v45.0, Vol 3, Part B, Sec 3.3
  enum class Size : uint8_t {
    kOneByte = 0,
    kTwoBytes = 1,
    kFourBytes = 2,
    kEightBytes = 3,
    kSixteenBytes = 4,
    kNextOne = 5,
    kNextTwo = 6,
    kNextFour = 7,
  };
  constexpr static uint8_t kSizeMask = 0x07;

  // Constructs a Null data element.
  DataElement();
  ~DataElement() = default;

  // Default move constructor and move-assigment
  DataElement(DataElement&&) = default;
  DataElement& operator=(DataElement&&) = default;

  // Convenience constructor to create a DataElement from a basic type.
  template <typename T>
  explicit DataElement(T value) {
    Set<T>(std::move(value));
  }

  // Make a deep copy of this element.
  DataElement Clone() const { return DataElement(*this); }

  // Reads a DataElement from |buffer|, replacing any data that was in |elem|.
  // Returns the amount of space occupied on |buffer| by the data element, or
  // zero if no element could be read.
  static size_t Read(DataElement* elem, const ByteBuffer& buffer);

  // The type of this element.
  Type type() const { return type_; }

  // The size of this element.
  Size size() const { return size_; }

  // Sets the value of this element to |value|.
  // Defined specializations:
  // typename                - type()
  // std::nullptr_t          - kNull
  // uint8_t, .., uint64_t   - kUnsignedInt
  // int8_t .. int64_t       - kSignedInt
  // const UUID&     - kUuid
  // const std::string&      - kString
  // bool                    - kBoolean
  // std::vector<DataElemnt> - kSequence
  // (not available)         - kUrl (not used in any known profiles)
  template <typename T>
  void Set(T value);

  // Sets this element's value to an alternative of the items in |items|
  void SetAlternative(std::vector<DataElement> items);

  // Get the value of this element.
  // Has the same defined specializations as Set().
  // Returns an optional without a value if the wrong type is stored.
  template <typename T>
  std::optional<T> Get() const;

  // Get a pointer to an element in a DataElement Sequence.
  // Returns nullptr if type() is not kSequence or the index is invalid.
  // Only valid as long as the containing sequence is valid.
  const DataElement* At(size_t idx) const;

  // Calculates the number of bytes that this DataElement will use if it's
  // written using Write().
  size_t WriteSize() const;

  // Writes this DataElement to |buffer|.
  // Returns the number of bytes used for writing this element.
  size_t Write(MutableByteBuffer* buffer) const;

  // Debug representation of this element (including it's type and size) in a
  // string, i.e. UnsignedInt:4(15) or Sequence { UUID(1567), UUID(2502) }
  std::string ToString() const;

 private:
  // Copy constructor for Clone(), no assignment operator.
  DataElement(const DataElement&);
  DataElement& operator=(const DataElement&) = delete;
  // Sets the size type based on a variable size (Next one, two, or four)
  void SetVariableSize(size_t length);

  Type type_;
  Size size_;

  // Various types for the stored value.  These are only valid if the type_ is
  // set correctly.
  int64_t int_value_;
  uint64_t uint_value_;
  UUID uuid_;
  std::string string_;
  std::vector<DataElement> aggregate_;
};

}  // namespace sdp
}  // namespace bt

#endif  // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_SDP_DATA_ELEMENT_H_
