// Copyright 2024 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/allocator.h"
#include "pw_allocator/chunk_pool.h"
#include "pw_bytes/span.h"
#include "pw_result/result.h"

namespace pw::allocator {

/// Typed pool that can be used for slab allocation.
///
/// This class is a special purpose pool designed to allocate objects of one
/// specific type, ``T``. It is useful when you need a dynamic pool of objects
/// with very low performance and memory overhead costs. For example, a
/// dispatcher might use such an allocator to manage memory for a set of task
/// objects.
///
/// @tparam   T   The type of object to allocate memory for.
template <typename T>
class TypedPool : public ChunkPool {
 public:
  /// Returns the amount of memory needed to allocate ``num_objects``.
  static constexpr size_t SizeNeeded(size_t num_objects) {
    size_t needed = std::max(sizeof(T), ChunkPool::kMinSize);
    PW_ASSERT(!PW_MUL_OVERFLOW(needed, num_objects, &needed));
    return needed;
  }

  /// Returns the optimal alignment for the backing memory region.
  static constexpr size_t AlignmentNeeded() {
    return std::max(alignof(T), ChunkPool::kMinAlignment);
  }

  /// Provides aligned storage for `kNumObjects` of type `T`.
  template <size_t kNumObjects>
  struct Buffer {
    static_assert(kNumObjects != 0);
    alignas(
        AlignmentNeeded()) std::array<std::byte, SizeNeeded(kNumObjects)> data;
  };

  /// Construct a ``TypedPool``.
  ///
  /// This constructor uses the `Buffer` type to minimize wasted memory. For
  /// example:
  ///
  /// @code{.cpp}
  /// TypedPool<MyObject>::Buffer<100> buffer;
  /// TypedPool<MyObject> my_pool(buffer);
  /// @endcode
  ///
  /// @param  buffer  The memory to allocate from.
  template <size_t kNumObjects>
  TypedPool(Buffer<kNumObjects>& buffer)
      : ChunkPool(buffer.data, Layout::Of<T>()) {}

  /// Construct a ``TypedPool``.
  ///
  /// To minimize wasted memory, align the buffer provided to the allocator to
  /// the object type's alignment. For example:
  ///
  /// @code{.cpp}
  /// alignas(MyObject) std::array<std::byte, 0x1000> buffer;
  /// TypedPool<MyObject> my_pool(buffer);
  /// @endcode
  ///
  /// @param  region  The memory to allocate from. Must be large enough to
  ///                 allocate memory for at least one object.
  TypedPool(ByteSpan region) : ChunkPool(region, Layout::Of<T>()) {}

  /// Constructs and object from the given `args`
  ///
  /// This method is similar to ``Allocator::New``, except that it is specific
  /// to the pool's object type.
  ///
  /// @param[in]  args...     Arguments passed to the object constructor.
  template <int&... ExplicitGuard, typename... Args>
  T* New(Args&&... args) {
    void* ptr = Allocate();
    return ptr != nullptr ? new (ptr) T(std::forward<Args>(args)...) : nullptr;
  }

  /// Constructs and object from the given `args`, and wraps it in a `UniquePtr`
  ///
  /// This method is similar to ``Allocator::MakeUnique``, except that it is
  /// specific to the pool's object type.
  ///
  /// @param[in]  args...     Arguments passed to the object constructor.
  template <int&... ExplicitGuard, typename... Args>
  UniquePtr<T> MakeUnique(Args&&... args) {
    return Deallocator::WrapUnique<T>(New(std::forward<Args>(args)...));
  }
};

}  // namespace pw::allocator
