// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef dap_any_h
#define dap_any_h

#include "typeinfo.h"

#include <assert.h>

namespace dap {

template <typename T>
struct TypeOf;

// any provides a type-safe container for values of any of dap type (boolean,
// integer, number, array, variant, any, null, dap-structs).
class any {
 public:
  // constructors
  inline any() = default;
  inline any(const any& other) noexcept;
  inline any(any&& other) noexcept;

  template <typename T>
  inline any(const T& val);

  // destructors
  inline ~any();

  // replaces the contained value with a null.
  inline void reset();

  // assignment
  inline any& operator=(const any& rhs);
  inline any& operator=(any&& rhs) noexcept;
  template <typename T>
  inline any& operator=(const T& val);

  // get() returns the contained value of the type T.
  // If the any does not contain a value of type T, then get() will assert.
  template <typename T>
  inline T& get() const;

  // is() returns true iff the contained value is of type T.
  template <typename T>
  inline bool is() const;

 private:
  static inline void* alignUp(void* val, size_t alignment);
  inline void alloc(size_t size, size_t align);
  inline void free();
  inline bool isInBuffer(void* ptr) const;

  void* value = nullptr;
  const TypeInfo* type = nullptr;
  void* heap = nullptr;  // heap allocation
  uint8_t buffer[32];    // or internal allocation
};

inline any::~any() {
  reset();
}

template <typename T>
inline any::any(const T& val) {
  *this = val;
}

any::any(const any& other) noexcept : type(other.type) {
  if (other.value != nullptr) {
    alloc(type->size(), type->alignment());
    type->copyConstruct(value, other.value);
  }
}

any::any(any&& other) noexcept : value(other.value), type(other.type) {
  other.value = nullptr;
  other.type = nullptr;
}

void any::reset() {
  if (value != nullptr) {
    type->destruct(value);
    free();
  }
  value = nullptr;
  type = nullptr;
}

any& any::operator=(const any& rhs) {
  reset();
  type = rhs.type;
  if (rhs.value != nullptr) {
    alloc(type->size(), type->alignment());
    type->copyConstruct(value, rhs.value);
  }
  return *this;
}

any& any::operator=(any&& rhs) noexcept {
  value = rhs.value;
  type = rhs.type;
  rhs.value = nullptr;
  rhs.type = nullptr;
  return *this;
}

template <typename T>
any& any::operator=(const T& val) {
  if (!is<T>()) {
    reset();
    type = TypeOf<T>::type();
    alloc(type->size(), type->alignment());
    type->copyConstruct(value, &val);
  } else {
    *reinterpret_cast<T*>(value) = val;
  }
  return *this;
}

template <typename T>
T& any::get() const {
  assert(is<T>());
  return *reinterpret_cast<T*>(value);
}

template <typename T>
bool any::is() const {
  return type == TypeOf<T>::type();
}

template <>
inline bool any::is<std::nullptr_t>() const {
  return value == nullptr;
}

void* any::alignUp(void* val, size_t alignment) {
  auto ptr = reinterpret_cast<uintptr_t>(val);
  return reinterpret_cast<void*>(alignment *
                                 ((ptr + alignment - 1) / alignment));
}

void any::alloc(size_t size, size_t align) {
  assert(value == nullptr);
  value = alignUp(buffer, align);
  if (isInBuffer(reinterpret_cast<uint8_t*>(value) + size - 1)) {
    return;
  }
  heap = new uint8_t[size + align];
  value = alignUp(heap, align);
}

void any::free() {
  assert(value != nullptr);
  if (heap != nullptr) {
    delete[] reinterpret_cast<uint8_t*>(heap);
    heap = nullptr;
  }
  value = nullptr;
}

bool any::isInBuffer(void* ptr) const {
  auto addr = reinterpret_cast<uintptr_t>(ptr);
  return addr >= reinterpret_cast<uintptr_t>(buffer) &&
         addr < reinterpret_cast<uintptr_t>(buffer + sizeof(buffer));
}

}  // namespace dap

#endif  // dap_any_h
