// Copyright 2023 The Pigweed Authors
//
// 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.
#pragma once

#include <cstddef>

#include "pw_allocator/capability.h"
#include "pw_allocator/deallocator.h"
#include "pw_allocator/layout.h"
#include "pw_allocator/unique_ptr.h"
#include "pw_result/result.h"

namespace pw {

/// Abstract interface for variable-layout memory allocation.
///
/// The interface makes no guarantees about its implementation. Consumers of the
/// generic interface must not make any assumptions around allocator behavior,
/// thread safety, or performance.
class Allocator : public Deallocator {
 public:
  /// Allocates a block of memory with the specified size and alignment.
  ///
  /// Returns `nullptr` if the allocation cannot be made, or the `layout` has a
  /// size of 0.
  ///
  /// @param[in]  layout      Describes the memory to be allocated.
  void* Allocate(Layout layout) {
    return layout.size() != 0 ? DoAllocate(layout) : nullptr;
  }

  /// Constructs and object of type `T` from the given `args`
  ///
  /// The return value is nullable, as allocating memory for the object may
  /// fail. Callers must check for this error before using the resulting
  /// pointer.
  ///
  /// @param[in]  args...     Arguments passed to the object constructor.
  template <typename T, int&... ExplicitGuard, typename... Args>
  T* New(Args&&... args) {
    void* ptr = Allocate(Layout::Of<T>());
    return ptr != nullptr ? new (ptr) T(std::forward<Args>(args)...) : nullptr;
  }

  /// Constructs and object of type `T` from the given `args`, and wraps it in a
  /// `UniquePtr`
  ///
  /// The returned value may contain null if allocating memory for the object
  /// fails. Callers must check for null before using the `UniquePtr`.
  ///
  /// @param[in]  args...     Arguments passed to the object constructor.
  template <typename T, int&... ExplicitGuard, typename... Args>
  [[nodiscard]] UniquePtr<T> MakeUnique(Args&&... args) {
    return Deallocator::WrapUnique<T>(New<T>(std::forward<Args>(args)...));
  }

  /// Modifies the size of an previously-allocated block of memory without
  /// copying any data.
  ///
  /// Returns true if its size was changed without copying data to a new
  /// allocation; otherwise returns false.
  ///
  /// In particular, it always returns true if the `old_layout.size()` equals
  /// `new_size`, and always returns false if the given pointer is null, the
  /// `old_layout.size()` is 0, or the `new_size` is 0.
  ///
  /// @param[in]  ptr           Pointer to previously-allocated memory.
  /// @param[in]  new_size      Requested new size for the memory allocation.
  bool Resize(void* ptr, size_t new_size) {
    return ptr != nullptr && new_size != 0 && DoResize(ptr, new_size);
  }

  /// Deprecated version of `Resize` that takes a `Layout`.
  /// Do not use this method. It will be removed.
  /// TODO(b/326509341): Remove when downstream consumers migrate.
  bool Resize(void* ptr, Layout layout, size_t new_size) {
    return ptr != nullptr && new_size != 0 && DoResize(ptr, layout, new_size);
  }

  /// Modifies the size of a previously-allocated block of memory.
  ///
  /// Returns pointer to the modified block of memory, or `nullptr` if the
  /// memory could not be modified.
  ///
  /// The data stored by the memory being modified must be trivially
  /// copyable. If it is not, callers should themselves attempt to `Resize`,
  /// then `Allocate`, move the data, and `Deallocate` as needed.
  ///
  /// If `nullptr` is returned, the block of memory is unchanged. In particular,
  /// if the `new_layout` has a size of 0, the given pointer will NOT be
  /// deallocated.
  ///
  /// TODO(b/331290408): This error condition needs to be better communicated to
  /// module users, who may assume the pointer is freed.
  ///
  /// Unlike `Resize`, providing a null pointer will return a new allocation.
  ///
  /// If the request can be satisfied using `Resize`, the `alignment` parameter
  /// may be ignored.
  ///
  /// @param[in]  ptr         Pointer to previously-allocated memory.
  /// @param[in]  new_layout  Describes the memory to be allocated.
  void* Reallocate(void* ptr, Layout new_layout) {
    if (new_layout.size() == 0) {
      return nullptr;
    }
    if (ptr == nullptr) {
      return Allocate(new_layout);
    }
    return DoReallocate(ptr, new_layout);
  }

  /// Deprecated version of `Reallocate` that takes a `Layout`.
  /// Do not use this method. It will be removed.
  /// TODO(b/326509341): Remove when downstream consumers migrate.
  void* Reallocate(void* ptr, Layout old_layout, size_t new_size) {
    if (new_size == 0) {
      return nullptr;
    }
    if (ptr == nullptr) {
      return Allocate(Layout(new_size, old_layout.alignment()));
    }
    return DoReallocate(ptr, old_layout, new_size);
  }

  /// Returns the layout used to allocate a given pointer.
  ///
  /// NOTE: This method will eventually be deprecated. Use `GetAllocatedLayout`
  /// instead.
  ///
  /// @returns @rst
  ///
  /// .. pw-status-codes::
  ///
  ///    OK: Returns the actual layout of allocated memory.
  ///
  ///    NOT_FOUND: The allocator does not recognize the pointer as one of
  ///    its allocations.
  ///
  ///    UNIMPLEMENTED: Allocator cannot recover allocation details.
  ///
  /// @endrst
  Result<Layout> GetLayout(const void* ptr) const {
    return GetAllocatedLayout(*this, ptr);
  }

 protected:
  /// TODO(b/326509341): Remove when downstream consumers migrate.
  constexpr Allocator() = default;

  explicit constexpr Allocator(const Capabilities& capabilities)
      : Deallocator(capabilities) {}

  /// Returns the layout that was requested when allocating a given pointer.
  ///
  /// This optional method can recover details about what memory was requested
  /// from a pointer previously allocated by a given object. The
  /// requested layout may differ from either the layout of usable memory, the
  /// layout of memory used to fulfill the request, or both.
  ///
  /// For example, it may have a smaller size than the usable memory if the
  /// latter was padded to an alignment boundary, or may have a less strict
  /// alignment than the actual memory.
  ///
  /// This method is protected in order to restrict it to object
  /// implementations. It is static and takes an ``allocator`` parameter in
  /// order to allow forwarding allocators to call it on wrapped allocators.
  ///
  /// @param[in]  allocator   The object that provided ``ptr``.
  /// @param[in]  ptr           A pointer to previously allocated memory.
  ///
  /// @returns @rst
  ///
  /// .. pw-status-codes::
  ///
  ///    OK: Returns the originally requested layout.
  ///
  ///    NOT_FOUND: The allocator does not recognize the pointer
  ///    as one of its allocations.
  ///
  ///    UNIMPLEMENTED: Implementation cannot recover allocation details.
  ///
  /// @endrst
  static Result<Layout> GetRequestedLayout(const Allocator& allocator,
                                           const void* ptr);

  /// Returns the layout of the usable memory associated with a given pointer.
  ///
  /// This optional method can recover details about what memory is usable for a
  /// pointer previously allocated by this object. The usable layout
  /// may from either the requested layout, the layout of memory used to fulfill
  /// the request, or both.
  ///
  /// For example, it may have a larger size than the requested layout if it
  /// was padded to an alignment boundary, but may be less than the acutal
  /// memory if the object includes some overhead for metadata.
  ///
  /// This method is protected in order to restrict it to object
  /// implementations. It is static and takes an ``allocator`` parameter in
  /// order to allow forwarding allocators to call it on wrapped allocators.
  ///
  /// @param[in]  allocator      The object that provided ``ptr``.
  /// @param[in]  ptr           A pointer to previously allocated memory.
  ///
  /// @returns @rst
  ///
  /// .. pw-status-codes::
  ///
  ///    OK: Returns the layout of usable memory.
  ///
  ///    NOT_FOUND: The allocator does not recognize the pointer as one of its
  ///    allocations.
  ///
  ///    UNIMPLEMENTED: Implementation cannot recover allocation details.
  ///
  /// @endrst
  static Result<Layout> GetUsableLayout(const Allocator& allocator,
                                        const void* ptr);

  /// Returns the layout of the memory used to allocate a given pointer.
  ///
  /// This optional method can recover details about what memory is usable for a
  /// pointer previously allocated by this object. The layout of memory
  /// used to fulfill a request may differ from either the requested layout, the
  /// layout of the usable memory, or both.
  ///
  /// For example, it may have a larger size than the requested layout or the
  /// layout of usable memory if the object includes some overhead for
  /// metadata.
  ///
  /// This method is protected in order to restrict it to object
  /// implementations. It is static and takes an ``allocator`` parameter in
  /// order to allow forwarding allocators to call it on wrapped allocators.
  ///
  /// @param[in]  allocator   The object that provided ``ptr``.
  /// @param[in]  ptr           A pointer to previously allocated memory.
  ///
  /// @returns @rst
  ///
  /// .. pw-status-codes::
  ///
  ///    OK: Returns the layout of usable memory.
  ///
  ///    NOT_FOUND: The allocator does not recognize the pointer as one of
  ///    its allocations.
  ///
  ///    UNIMPLEMENTED: Implementation cannot recover allocation details.
  ///
  /// @endrst
  static Result<Layout> GetAllocatedLayout(const Allocator& allocator,
                                           const void* ptr);

 private:
  /// Virtual `Allocate` function implemented by derived classes.
  ///
  /// @param[in]  layout        Describes the memory to be allocated. Guaranteed
  ///                           to have a non-zero size.
  virtual void* DoAllocate(Layout layout) = 0;

  /// Virtual `Resize` function implemented by derived classes.
  ///
  /// The default implementation simply returns `false`, indicating that
  /// resizing is not supported.
  ///
  /// @param[in]  ptr           Pointer to memory, guaranteed to not be null.
  /// @param[in]  new_size      Requested size, guaranteed to be non-zero..
  virtual bool DoResize(void* /*ptr*/, size_t /*new_size*/) { return false; }

  /// Deprecated version of `DoResize` that takes a `Layout`.
  /// Do not use this method. It will be removed.
  /// TODO(b/326509341): Remove when downstream consumers migrate.
  virtual bool DoResize(void*, Layout, size_t) { return false; }

  /// Virtual `Reallocate` function that can be overridden by derived classes.
  ///
  /// The default implementation will first try to `Resize` the data. If that is
  /// unsuccessful, it will allocate an entirely new block, copy existing data,
  /// and deallocate the given block.
  ///
  /// @param[in]  ptr           Pointer to memory, guaranteed to not be null.
  /// @param[in]  new_layout    Describes the memory to be allocated. Guaranteed
  ///                           to have a non-zero size.
  virtual void* DoReallocate(void* ptr, Layout new_layout);

  /// Deprecated version of `DoReallocate` that takes a `Layout`.
  /// Do not use this method. It will be removed.
  /// TODO(b/326509341): Remove when downstream consumers migrate.
  virtual void* DoReallocate(void* ptr, Layout old_layout, size_t new_size);

  /// Virtual `GetRequested` function that can be overridden by derived classes.
  ///
  /// The default implementation of this method simply returns `UNIMPLEMENTED`,
  /// indicating the allocator cannot recover layouts from allocated pointers.
  ///
  /// @param[in]  ptr           Pointer to memory, guaranteed to not be null.
  virtual Result<Layout> DoGetRequestedLayout(const void*) const;

  /// Virtual `Query` function that can be overridden by derived classes.
  virtual Result<Layout> DoGetUsableLayout(const void*) const;

  /// Virtual `Query` function that can be overridden by derived classes.
  virtual Result<Layout> DoGetAllocatedLayout(const void*) const;
};

namespace allocator {

// Alias for module consumers using the older name for the above type.
using Allocator = ::pw::Allocator;

}  // namespace allocator
}  // namespace pw
