// 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)
    IntWrapper(int /* dummy */) {}  // do nothing
  };

  // 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_
