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

// Internal implementation of brillo::Any class.

#ifndef LIBBRILLO_BRILLO_ANY_INTERNAL_IMPL_H_
#define LIBBRILLO_BRILLO_ANY_INTERNAL_IMPL_H_

#include <type_traits>
#include <typeinfo>
#include <utility>

#include <base/logging.h>
#include <brillo/dbus/data_serialization.h>
#include <brillo/type_name_undecorate.h>

namespace brillo {

namespace internal_details {

// An extension to std::is_convertible to allow conversion from an enum to
// an integral type which std::is_convertible does not indicate as supported.
template <typename From, typename To>
struct IsConvertible
    : public std::integral_constant<
          bool,
          std::is_convertible<From, To>::value ||
              (std::is_enum<From>::value && std::is_integral<To>::value)> {};

// TryConvert is a helper function that does a safe compile-time conditional
// type cast between data types that may not be always convertible.
// From and To are the source and destination types.
// The function returns true if conversion was possible/successful.
template <typename From, typename To>
inline typename std::enable_if<IsConvertible<From, To>::value, bool>::type
TryConvert(const From& in, To* out) {
  *out = static_cast<To>(in);
  return true;
}
template <typename From, typename To>
inline typename std::enable_if<!IsConvertible<From, To>::value, bool>::type
TryConvert(const From& /* in */, To* /* out */) {
  return false;
}

//////////////////////////////////////////////////////////////////////////////
// Provide a way to compare values of unspecified types without compiler errors
// when no operator==() is provided for a given type. This is important to
// allow Any class to have operator==(), yet still allowing arbitrary types
// (not necessarily comparable) to be placed inside Any without resulting in
// compile-time error.
//
// We achieve this in two ways. First, we provide a IsEqualityComparable<T>
// class that can be used in compile-time conditions to determine if there is
// operator==() defined that takes values of type T (or which can be implicitly
// converted to type T). Secondly, this allows us to specialize a helper
// compare function EqCompare<T>(v1, v2) to use operator==() for types that
// are comparable, and just return false for those that are not.
//
// IsEqualityComparableHelper<T> is a helper class for implementing an
// an STL-compatible IsEqualityComparable<T> containing a Boolean member |value|
// which evaluates to true for comparable types and false otherwise.
template<typename T>
struct IsEqualityComparableHelper {
  struct IntWrapper {
    // A special structure that provides a constructor that takes an int.
    // This way, an int argument passed to a function will be favored over
    // IntWrapper when both overloads are provided.
    // Also this constructor must NOT be explicit.
    // NOLINTNEXTLINE(runtime/explicit)
    // NOLINT: Allow implicit conversion from int.
    IntWrapper(int /* dummy */) {}  // do nothing, NOLINT
  };

  // Here is an obscure trick to determine if a type U has operator==().
  // We are providing two function prototypes for TriggerFunction. One that
  // takes an argument of type IntWrapper (which is implicitly convertible from
  // an int), and returns an std::false_type. This is a fall-back mechanism.
  template<typename U>
  static std::false_type TriggerFunction(IntWrapper dummy);

  // The second overload of TriggerFunction takes an int (explicitly) and
  // returns std::true_type. If both overloads are available, this one will be
  // chosen when referencing it as TriggerFunction(0), since it is a better
  // (more specific) match.
  //
  // However this overload is available only for types that support operator==.
  // This is achieved by employing SFINAE mechanism inside a template function
  // overload that refers to operator==() for two values of types U&. This is
  // used inside decltype(), so no actual code is executed. If the types
  // are not comparable, reference to "==" would fail and the compiler will
  // simply ignore this overload due to SFIANE.
  //
  // The final little trick used here is the reliance on operator comma inside
  // the decltype() expression. The result of the expression is always
  // std::true_type(). The expression on the left of comma is just evaluated and
  // discarded. If it evaluates successfully (i.e. the type has operator==), the
  // return value of the function is set to be std::true_value. If it fails,
  // the whole function prototype is discarded and is not available in the
  // IsEqualityComparableHelper<T> class.
  //
  // Here we use std::declval<U&>() to make sure we have operator==() that takes
  // lvalue references to type U which is not necessarily default-constructible.
  template<typename U>
  static decltype((std::declval<U&>() == std::declval<U&>()), std::true_type())
  TriggerFunction(int dummy);

  // Finally, use the return type of the overload of TriggerFunction that
  // matches the argument (int) to be aliased to type |type|. If T is
  // comparable, there will be two overloads and the more specific (int) will
  // be chosen which returns std::true_value. If the type is non-comparable,
  // there will be only one version of TriggerFunction available which
  // returns std::false_value.
  using type = decltype(TriggerFunction<T>(0));
};

// IsEqualityComparable<T> is simply a class that derives from either
// std::true_value, if type T is comparable, or from std::false_value, if the
// type is non-comparable. We just use |type| alias from
// IsEqualityComparableHelper<T> as the base class.
template<typename T>
struct IsEqualityComparable : IsEqualityComparableHelper<T>::type {};

// EqCompare() overload for non-comparable types. Always returns false.
template<typename T>
inline typename std::enable_if<!IsEqualityComparable<T>::value, bool>::type
EqCompare(const T& /* v1 */, const T& /* v2 */) {
  return false;
}

// EqCompare overload for comparable types. Calls operator==(v1, v2) to compare.
template<typename T>
inline typename std::enable_if<IsEqualityComparable<T>::value, bool>::type
EqCompare(const T& v1, const T& v2) {
  return (v1 == v2);
}

//////////////////////////////////////////////////////////////////////////////

class Buffer;  // Forward declaration of data buffer container.

// Abstract base class for contained variant data.
struct Data {
  virtual ~Data() {}
  // Returns the type tag (name) for the contained data.
  virtual const char* GetTypeTag() const = 0;
  // Copies the contained data to the output |buffer|.
  virtual void CopyTo(Buffer* buffer) const = 0;
  // Moves the contained data to the output |buffer|.
  virtual void MoveTo(Buffer* buffer) = 0;
  // Checks if the contained data is an integer type (not necessarily an 'int').
  virtual bool IsConvertibleToInteger() const = 0;
  // Gets the contained integral value as an integer.
  virtual intmax_t GetAsInteger() const = 0;
  // Writes the contained value to the D-Bus message buffer.
  virtual void AppendToDBusMessage(::dbus::MessageWriter* writer) const = 0;
  // Compares if the two data containers have objects of the same value.
  virtual bool CompareEqual(const Data* other_data) const = 0;
};

// Concrete implementation of variant data of type T.
template<typename T>
struct TypedData : public Data {
  explicit TypedData(const T& value) : value_(value) {}
  // NOLINTNEXTLINE(build/c++11)
  explicit TypedData(T&& value) : value_(std::move(value)) {}

  const char* GetTypeTag() const override { return brillo::GetTypeTag<T>(); }
  void CopyTo(Buffer* buffer) const override;
  void MoveTo(Buffer* buffer) override;
  bool IsConvertibleToInteger() const override {
    return std::is_integral<T>::value || std::is_enum<T>::value;
  }
  intmax_t GetAsInteger() const override {
    intmax_t int_val = 0;
    bool converted = TryConvert(value_, &int_val);
    CHECK(converted) << "Unable to convert value of type '"
                     << GetUndecoratedTypeName<T>() << "' to integer";
    return int_val;
  }

  template <typename U>
  static typename std::enable_if<dbus_utils::IsTypeSupported<U>::value>::type
  AppendValueHelper(::dbus::MessageWriter* writer, const U& value) {
    brillo::dbus_utils::AppendValueToWriterAsVariant(writer, value);
  }
  template <typename U>
  static typename std::enable_if<!dbus_utils::IsTypeSupported<U>::value>::type
  AppendValueHelper(::dbus::MessageWriter* /* writer */, const U& /* value */) {
    LOG(FATAL) << "Type '" << GetUndecoratedTypeName<U>()
               << "' is not supported by D-Bus";
  }

  void AppendToDBusMessage(::dbus::MessageWriter* writer) const override {
    return AppendValueHelper(writer, value_);
  }

  bool CompareEqual(const Data* other_data) const override {
    return EqCompare<T>(value_,
                        static_cast<const TypedData<T>*>(other_data)->value_);
  }

  // Special methods to copy/move data of the same type
  // without reallocating the buffer.
  void FastAssign(const T& source) { value_ = source; }
  // NOLINTNEXTLINE(build/c++11)
  void FastAssign(T&& source) { value_ = std::move(source); }

  T value_;
};

// Buffer class that stores the contained variant data.
// To improve performance and reduce memory fragmentation, small variants
// are stored in pre-allocated memory buffers that are part of the Any class.
// If the memory requirements are larger than the set limit or the type is
// non-trivially copyable, then the contained class is allocated in a separate
// memory block and the pointer to that memory is contained within this memory
// buffer class.
class Buffer final {
 public:
  enum StorageType { kExternal, kContained };
  Buffer() : external_ptr_(nullptr), storage_(kExternal) {}
  ~Buffer() { Clear(); }

  Buffer(const Buffer& rhs) : Buffer() { rhs.CopyTo(this); }
  // NOLINTNEXTLINE(build/c++11)
  Buffer(Buffer&& rhs) : Buffer() { rhs.MoveTo(this); }
  Buffer& operator=(const Buffer& rhs) {
    rhs.CopyTo(this);
    return *this;
  }
  // NOLINTNEXTLINE(build/c++11)
  Buffer& operator=(Buffer&& rhs) {
    rhs.MoveTo(this);
    return *this;
  }

  // Returns the underlying pointer to contained data. Uses either the pointer
  // or the raw data depending on |storage_| type.
  inline Data* GetDataPtr() {
    return (storage_ == kExternal) ? external_ptr_
                                   : reinterpret_cast<Data*>(contained_buffer_);
  }
  inline const Data* GetDataPtr() const {
    return (storage_ == kExternal)
               ? external_ptr_
               : reinterpret_cast<const Data*>(contained_buffer_);
  }

  // Destroys the contained object (and frees memory if needed).
  void Clear() {
    Data* data = GetDataPtr();
    if (storage_ == kExternal) {
      delete data;
    } else {
      // Call the destructor manually, since the object was constructed inline
      // in the pre-allocated buffer. We still need to call the destructor
      // to free any associated resources, but we can't call delete |data| here.
      data->~Data();
    }
    external_ptr_ = nullptr;
    storage_ = kExternal;
  }

  // Stores a value of type T.
  template<typename T>
  void Assign(T&& value) {  // NOLINT(build/c++11)
    using Type = typename std::decay<T>::type;
    using DataType = TypedData<Type>;
    Data* ptr = GetDataPtr();
    if (ptr && strcmp(ptr->GetTypeTag(), GetTypeTag<Type>()) == 0) {
      // We assign the data to the variant container, which already
      // has the data of the same type. Do fast copy/move with no memory
      // reallocation.
      DataType* typed_ptr = static_cast<DataType*>(ptr);
      // NOLINTNEXTLINE(build/c++11)
      typed_ptr->FastAssign(std::forward<T>(value));
    } else {
      Clear();
      // TODO(avakulenko): [see crbug.com/379833]
      // Unfortunately, GCC doesn't support std::is_trivially_copyable<T> yet,
      // so using std::is_trivial instead, which is a bit more restrictive.
      // Once GCC has support for is_trivially_copyable, update the following.
      if (!std::is_trivial<Type>::value ||
          sizeof(DataType) > sizeof(contained_buffer_)) {
        // If it is too big or not trivially copyable, allocate it separately.
        // NOLINTNEXTLINE(build/c++11)
        external_ptr_ = new DataType(std::forward<T>(value));
        storage_ = kExternal;
      } else {
        // Otherwise just use the pre-allocated buffer.
        DataType* address = reinterpret_cast<DataType*>(contained_buffer_);
        // Make sure we still call the copy/move constructor.
        // Call the constructor manually by using placement 'new'.
        // NOLINTNEXTLINE(build/c++11)
        new (address) DataType(std::forward<T>(value));
        storage_ = kContained;
      }
    }
  }

  // Helper methods to retrieve a reference to contained data.
  // These assume that type checking has already been performed by Any
  // so the type cast is valid and will succeed.
  template<typename T>
  const T& GetData() const {
    using DataType = internal_details::TypedData<typename std::decay<T>::type>;
    return static_cast<const DataType*>(GetDataPtr())->value_;
  }
  template<typename T>
  T& GetData() {
    using DataType = internal_details::TypedData<typename std::decay<T>::type>;
    return static_cast<DataType*>(GetDataPtr())->value_;
  }

  // Returns true if the buffer has no contained data.
  bool IsEmpty() const {
    return (storage_ == kExternal && external_ptr_ == nullptr);
  }

  // Copies the data from the current buffer into the |destination|.
  void CopyTo(Buffer* destination) const {
    if (IsEmpty()) {
      destination->Clear();
    } else {
      GetDataPtr()->CopyTo(destination);
    }
  }

  // Moves the data from the current buffer into the |destination|.
  void MoveTo(Buffer* destination) {
    if (IsEmpty()) {
      destination->Clear();
    } else {
      if (storage_ == kExternal) {
        destination->Clear();
        destination->storage_ = kExternal;
        destination->external_ptr_ = external_ptr_;
        external_ptr_ = nullptr;
      } else {
        GetDataPtr()->MoveTo(destination);
      }
    }
  }

  union {
    // |external_ptr_| is a pointer to a larger object allocated in
    // a separate memory block.
    Data* external_ptr_;
    // |contained_buffer_| is a pre-allocated buffer for smaller/simple objects.
    // Pre-allocate enough memory to store objects as big as "double".
    unsigned char contained_buffer_[sizeof(TypedData<double>)];
  };
  // Depending on a value of |storage_|, either |external_ptr_| or
  // |contained_buffer_| above is used to get a pointer to memory containing
  // the variant data.
  StorageType storage_;  // Declare after the union to eliminate member padding.
};

template <typename T>
void TypedData<T>::CopyTo(Buffer* buffer) const {
  buffer->Assign(value_);
}
template <typename T>
void TypedData<T>::MoveTo(Buffer* buffer) {
  buffer->Assign(std::move(value_));
}

}  // namespace internal_details

}  // namespace brillo

#endif  // LIBBRILLO_BRILLO_ANY_INTERNAL_IMPL_H_
