/*
 * Copyright 2021 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef sktext_gpu_SubRunAllocator_DEFINED
#define sktext_gpu_SubRunAllocator_DEFINED

#include "include/core/SkSpan.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkMath.h"
#include "include/private/base/SkTLogic.h"
#include "include/private/base/SkTemplates.h"
#include "include/private/base/SkTo.h"
#include "src/base/SkArenaAlloc.h"

#include <algorithm>
#include <array>
#include <climits>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <limits>
#include <memory>
#include <new>
#include <tuple>
#include <utility>

namespace sktext::gpu {

// BagOfBytes parcels out bytes with a given size and alignment.
class BagOfBytes {
    // The maximum alignment supported by GrBagOfBytes. 16 seems to be a good number for alignment.
    // If a use case for larger alignments is found, we can turn this into a template parameter.
    inline static constexpr int kMaxAlignment = std::max(16, (int)alignof(std::max_align_t));
    // The largest size that can be allocated. In larger sizes, the block is rounded up to 4K
    // chunks. Leave a 4K of slop.
    inline static constexpr int k4K = (1 << 12);
    // This should never overflow with the calculations done on the code.
    inline static constexpr int kMaxByteSize = std::numeric_limits<int>::max() - k4K;
    // The assumed alignment of new char[] given the platform.
    // There is a bug in Emscripten's allocator that make alignment different than max_align_t.
    // kAllocationAlignment accounts for this difference. For more information see:
    // https://github.com/emscripten-core/emscripten/issues/10072
#if !defined(SK_FORCE_8_BYTE_ALIGNMENT)
    static constexpr int kAllocationAlignment = alignof(std::max_align_t);
#else
    static constexpr int kAllocationAlignment = 8;
#endif

public:
    BagOfBytes(char* block, size_t blockSize, size_t firstHeapAllocation);
    explicit BagOfBytes(size_t firstHeapAllocation = 0);
    BagOfBytes(const BagOfBytes&) = delete;
    BagOfBytes& operator=(const BagOfBytes&) = delete;
    BagOfBytes(BagOfBytes&& that)
            : fEndByte{std::exchange(that.fEndByte, nullptr)}
            , fCapacity{that.fCapacity}
            , fFibProgression{that.fFibProgression} {}
    BagOfBytes& operator=(BagOfBytes&& that) {
        this->~BagOfBytes();
        new (this) BagOfBytes{std::move(that)};
        return *this;
    }

    ~BagOfBytes();

    // Given a requestedSize round up to the smallest size that accounts for all the per block
    // overhead and alignment. It crashes if requestedSize is negative or too big.
    static constexpr int PlatformMinimumSizeWithOverhead(int requestedSize, int assumedAlignment) {
        return MinimumSizeWithOverhead(
                requestedSize, assumedAlignment, sizeof(Block), kMaxAlignment);
    }

    static constexpr int MinimumSizeWithOverhead(
            int requestedSize, int assumedAlignment, int blockSize, int maxAlignment) {
        SkASSERT_RELEASE(0 <= requestedSize && requestedSize < kMaxByteSize);
        SkASSERT_RELEASE(SkIsPow2(assumedAlignment) && SkIsPow2(maxAlignment));

        const int minAlignment = std::min(maxAlignment, assumedAlignment);
        // There are two cases, one easy and one subtle. The easy case is when minAlignment ==
        // maxAlignment. When that happens, the term maxAlignment - minAlignment is zero, and the
        // block will be placed at the proper alignment because alignUp is properly
        // aligned.
        // The subtle case is where minAlignment < maxAlignment. Because
        // minAlignment < maxAlignment, alignUp(requestedSize, minAlignment) + blockSize does not
        // guarantee that block can be placed at a maxAlignment address. Block can be placed at
        // maxAlignment/minAlignment different address to achieve alignment, so we need
        // to add memory to allow the block to be placed on a maxAlignment address.
        // For example, if assumedAlignment = 4 and maxAlignment = 16 then block can be placed at
        // the following address offsets at the end of minimumSize bytes.
        //   0 * minAlignment =  0
        //   1 * minAlignment =  4
        //   2 * minAlignment =  8
        //   3 * minAlignment = 12
        // Following this logic, the equation for the additional bytes is
        //   (maxAlignment/minAlignment - 1) * minAlignment
        //     = maxAlignment - minAlignment.
        int minimumSize = SkToInt(AlignUp(requestedSize, minAlignment))
                          + blockSize
                          + maxAlignment - minAlignment;

        // If minimumSize is > 32k then round to a 4K boundary unless it is too close to the
        // maximum int. The > 32K heuristic is from the JEMalloc behavior.
        constexpr int k32K = (1 << 15);
        if (minimumSize >= k32K && minimumSize < std::numeric_limits<int>::max() - k4K) {
            minimumSize = SkToInt(AlignUp(minimumSize, k4K));
        }

        return minimumSize;
    }

    template <int size>
    using Storage = std::array<char, PlatformMinimumSizeWithOverhead(size, 1)>;

    // Returns true if n * sizeof(T) will fit in an allocation block.
    template <typename T>
    static bool WillCountFit(int n) {
        constexpr int kMaxN = kMaxByteSize / sizeof(T);
        return 0 <= n && n < kMaxN;
    }

    // Returns a pointer to memory suitable for holding n values each with Size and Alignment.
    // Allocates 1 aligned byte if n == 0.
    template <size_t Size, size_t Alignment> char* allocateBytesFor(int n = 1)
        requires (Alignment <= kMaxAlignment && Size < kMaxByteSize && Size % Alignment == 0) {
        int size = n ? n * Size : 1;
        SkASSERT_RELEASE(size <= kMaxByteSize);
        return this->allocateBytes(size, Alignment);
    }

    template <typename T> char* allocateBytesFor(int n = 1) {
        return allocateBytesFor<sizeof(T), alignof(T)>(n);
    }

    void* alignedBytes(int unsafeSize, int unsafeAlignment);

private:
    static constexpr size_t AlignUp(int size, int alignment) {
        return (size + (alignment - 1)) & -alignment;
    }

    // The Block starts at the location pointed to by fEndByte.
    // Beware. Order is important here. The destructor for fPrevious must be called first because
    // the Block is embedded in fBlockStart. Destructors are run in reverse order.
    struct Block {
        Block(char* previous, char* startOfBlock);
        // The start of the originally allocated bytes. This is the thing that must be deleted.
        char* const fBlockStart;
        Block* const fPrevious;
    };

    // Note: fCapacity is the number of bytes remaining, and is subtracted from fEndByte to
    // generate the location of the object.
    char* allocateBytes(int size, int alignment) {
        fCapacity = fCapacity & -alignment;
        if (fCapacity < size) {
            this->needMoreBytes(size, alignment);
        }
        char* const ptr = fEndByte - fCapacity;
        SkASSERT(((intptr_t)ptr & (alignment - 1)) == 0);
        SkASSERT(fCapacity >= size);
        fCapacity -= size;
        return ptr;
    }

    // Adjust fEndByte and fCapacity give a new block starting at bytes with size.
    void setupBytesAndCapacity(char* bytes, int size);

    // Adjust fEndByte and fCapacity to satisfy the size and alignment request.
    void needMoreBytes(int size, int alignment);

    // This points to the highest kMaxAlignment address in the allocated block. The address of
    // the current end of allocated data is given by fEndByte - fCapacity. While the negative side
    // of this pointer are the bytes to be allocated. The positive side points to the Block for
    // this memory. In other words, the pointer to the Block structure for these bytes is
    // reinterpret_cast<Block*>(fEndByte).
    char* fEndByte{nullptr};

    // The number of bytes remaining in this block.
    int fCapacity{0};

    SkFibBlockSizes<kMaxByteSize> fFibProgression;
};

template <typename T>
class SubRunInitializer {
public:
    SubRunInitializer(void* memory) : fMemory{memory} { SkASSERT(memory != nullptr); }
    ~SubRunInitializer() {
        ::operator delete(fMemory);
    }
    template <typename... Args>
    T* initialize(Args&&... args) {
        // Warn on more than one initialization.
        SkASSERT(fMemory != nullptr);
        return new (std::exchange(fMemory, nullptr)) T(std::forward<Args>(args)...);
    }

private:
    void* fMemory;
};

// GrSubRunAllocator provides fast allocation where the user takes care of calling the destructors
// of the returned pointers, and GrSubRunAllocator takes care of deleting the storage. The
// unique_ptrs returned, are to assist in assuring the object's destructor is called.
// A note on zero length arrays: according to the standard a pointer must be returned, and it
// can't be a nullptr. In such a case, SkArena allocates one byte, but does not initialize it.
class SubRunAllocator {
public:
    struct Destroyer {
        template <typename T>
        void operator()(T* ptr) { ptr->~T(); }
    };

    struct ArrayDestroyer {
        int n;
        template <typename T>
        void operator()(T* ptr) {
            for (int i = 0; i < n; i++) { ptr[i].~T(); }
        }
    };

    template<class T>
    inline static constexpr bool HasNoDestructor = std::is_trivially_destructible<T>::value;

    SubRunAllocator(char* block, int blockSize, int firstHeapAllocation);
    explicit SubRunAllocator(int firstHeapAllocation = 0);
    SubRunAllocator(const SubRunAllocator&) = delete;
    SubRunAllocator& operator=(const SubRunAllocator&) = delete;
    SubRunAllocator(SubRunAllocator&&) = default;
    SubRunAllocator& operator=(SubRunAllocator&&) = default;

    template <typename T>
    static std::tuple<SubRunInitializer<T>, int, SubRunAllocator>
    AllocateClassMemoryAndArena(int allocSizeHint) {
        SkASSERT_RELEASE(allocSizeHint >= 0);
        // Round the size after the object the optimal amount.
        int extraSize = BagOfBytes::PlatformMinimumSizeWithOverhead(allocSizeHint, alignof(T));

        // Don't overflow or die.
        SkASSERT_RELEASE(INT_MAX - SkTo<int>(sizeof(T)) > extraSize);
        int totalMemorySize = sizeof(T) + extraSize;

        void* memory = ::operator new (totalMemorySize);
        SubRunAllocator alloc{SkTAddOffset<char>(memory, sizeof(T)), extraSize, extraSize/2};
        return {memory, totalMemorySize, std::move(alloc)};
    }

    template <typename T, typename... Args> T* makePOD(Args&&... args) {
        static_assert(HasNoDestructor<T>, "This is not POD. Use makeUnique.");
        char* bytes = fAlloc.template allocateBytesFor<T>();
        return new (bytes) T(std::forward<Args>(args)...);
    }

    template <typename T, typename... Args>
    std::unique_ptr<T, Destroyer> makeUnique(Args&&... args) {
        static_assert(!HasNoDestructor<T>, "This is POD. Use makePOD.");
        char* bytes = fAlloc.template allocateBytesFor<T>();
        return std::unique_ptr<T, Destroyer>{new (bytes) T(std::forward<Args>(args)...)};
    }

    template<typename T, size_t Alignment = alignof(T)> T* makePODArray(int n)
        requires (sizeof(T) % Alignment == 0) {
        static_assert(HasNoDestructor<T>, "This is not POD. Use makeUniqueArray.");
        return reinterpret_cast<T*>(fAlloc.template allocateBytesFor<sizeof(T), Alignment>(n));
    }

    template<typename T>
    SkSpan<T> makePODSpan(SkSpan<const T> s) {
        static_assert(HasNoDestructor<T>, "This is not POD. Use makeUniqueArray.");
        if (s.empty()) {
            return SkSpan<T>{};
        }

        T* result = this->makePODArray<T>(SkTo<int>(s.size()));
        memcpy(result, s.data(), s.size_bytes());
        return {result, s.size()};
    }

    template<typename T, typename Src, typename Map>
    SkSpan<T> makePODArray(const Src& src, Map map) {
        static_assert(HasNoDestructor<T>, "This is not POD. Use makeUniqueArray.");
        int size = SkTo<int>(src.size());
        T* result = this->template makePODArray<T>(size);
        for (int i = 0; i < size; i++) {
            new (&result[i]) T(map(src[i]));
        }
        return {result, src.size()};
    }

    template<typename T>
    std::unique_ptr<T[], ArrayDestroyer> makeUniqueArray(int n) {
        static_assert(!HasNoDestructor<T>, "This is POD. Use makePODArray.");
        T* array = reinterpret_cast<T*>(fAlloc.template allocateBytesFor<T>(n));
        for (int i = 0; i < n; i++) {
            new (&array[i]) T{};
        }
        return std::unique_ptr<T[], ArrayDestroyer>{array, ArrayDestroyer{n}};
    }

    template<typename T, typename I>
    std::unique_ptr<T[], ArrayDestroyer> makeUniqueArray(int n, I initializer) {
        static_assert(!HasNoDestructor<T>, "This is POD. Use makePODArray.");
        T* array = reinterpret_cast<T*>(fAlloc.template allocateBytesFor<T>(n));
        for (int i = 0; i < n; i++) {
            new (&array[i]) T(initializer(i));
        }
        return std::unique_ptr<T[], ArrayDestroyer>{array, ArrayDestroyer{n}};
    }

    template<typename T, typename U, typename Map>
    std::unique_ptr<T[], ArrayDestroyer> makeUniqueArray(SkSpan<const U> src, Map map) {
        static_assert(!HasNoDestructor<T>, "This is POD. Use makePODArray.");
        int count = SkCount(src);
        T* array = reinterpret_cast<T*>(fAlloc.template allocateBytesFor<T>(src.size()));
        for (int i = 0; i < count; ++i) {
            new (&array[i]) T(map(src[i]));
        }
        return std::unique_ptr<T[], ArrayDestroyer>{array, ArrayDestroyer{count}};
    }

    void* alignedBytes(int size, int alignment);

private:
    BagOfBytes fAlloc;
};

// Helper for defining allocators with inline/reserved storage.
// For argument declarations, stick to the base type (SubRunAllocator).
// Note: Inheriting from the storage first means the storage will outlive the
// SubRunAllocator, letting ~SubRunAllocator read it as it calls destructors.
// (This is mostly only relevant for strict tools like MSAN.)
template <size_t InlineStorageSize, size_t InlineStorageAlignment>
class STSubRunAllocator : private std::array<char,
                                             BagOfBytes::PlatformMinimumSizeWithOverhead(
                                                     InlineStorageSize, InlineStorageAlignment)>,
                          public SubRunAllocator {
public:
    explicit STSubRunAllocator(size_t firstHeapAllocation = InlineStorageSize)
            : SubRunAllocator{this->data(), SkToInt(this->size()), SkToInt(firstHeapAllocation)} {}
};
}  // namespace sktext::gpu

#endif // sktext_gpu_SubRunAllocator_DEFINED
