/*
* Copyright 2022 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_SubRunContainer_DEFINED
#define sktext_gpu_SubRunContainer_DEFINED

#include "include/core/SkMatrix.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSpan.h"
#include "src/text/gpu/SubRunAllocator.h"

#include <cstddef>
#include <functional>
#include <iterator>
#include <memory>
#include <tuple>
#include <utility>

class SkCanvas;
class SkPaint;
class SkReadBuffer;
class SkStrikeClient;
class SkWriteBuffer;
struct SkPoint;
struct SkStrikeDeviceInfo;

namespace sktext {
class GlyphRunList;
class StrikeForGPUCacheInterface;
}

namespace skgpu {
enum class MaskFormat : int;
}

#if defined(SK_GANESH) || defined(SK_USE_LEGACY_GANESH_TEXT_APIS)
#include "src/gpu/ganesh/GrColor.h"
#include "src/gpu/ganesh/ops/GrOp.h"

class GrClip;
struct SkIRect;
namespace skgpu::ganesh {
class SurfaceDrawContext;
}
#endif

namespace sktext::gpu {
class GlyphVector;
class Glyph;
class StrikeCache;
class VertexFiller;

using RegenerateAtlasDelegate = std::function<std::tuple<bool, int>(GlyphVector*,
                                                                    int begin,
                                                                    int end,
                                                                    skgpu::MaskFormat,
                                                                    int padding)>;

struct RendererData {
    bool isSDF = false;
    bool isLCD = false;
    skgpu::MaskFormat maskFormat;
};

// -- AtlasSubRun --------------------------------------------------------------------------------
// AtlasSubRun is the API that AtlasTextOp uses to generate vertex data for drawing.
//     There are three different ways AtlasSubRun is specialized.
//      * DirectMaskSubRun* - this is by far the most common type of SubRun. The mask pixels are
//        in 1:1 correspondence with the pixels on the device. The destination rectangles in this
//        SubRun are in device space. This SubRun handles color glyphs.
//      * TransformedMaskSubRun* - handles glyph where the image in the atlas needs to be
//        transformed to the screen. It is usually used for large color glyph which can't be
//        drawn with paths or scaled distance fields, but will be used to draw bitmap glyphs to
//        the screen, if the matrix does not map 1:1 to the screen. The destination rectangles
//        are in source space.
//      * SDFTSubRun* - scaled distance field text handles largish single color glyphs that still
//        can fit in the atlas; the sizes between direct SubRun, and path SubRun. The destination
//        rectangles are in source space.
class AtlasSubRun {
public:
    virtual ~AtlasSubRun() = default;

    virtual SkSpan<const Glyph*> glyphs() const = 0;
    virtual int glyphCount() const = 0;
    virtual skgpu::MaskFormat maskFormat() const = 0;
    virtual int glyphSrcPadding() const = 0;
    virtual unsigned short instanceFlags() const = 0;

#if defined(SK_GANESH) || defined(SK_USE_LEGACY_GANESH_TEXT_APIS)
    virtual size_t vertexStride(const SkMatrix& drawMatrix) const = 0;

    virtual std::tuple<const GrClip*, GrOp::Owner> makeAtlasTextOp(
            const GrClip*,
            const SkMatrix& viewMatrix,
            SkPoint drawOrigin,
            const SkPaint&,
            sk_sp<SkRefCnt>&& subRunStorage,
            skgpu::ganesh::SurfaceDrawContext*) const = 0;

    virtual void fillVertexData(
            void* vertexDst, int offset, int count,
            GrColor color,
            const SkMatrix& drawMatrix,
            SkPoint drawOrigin,
            SkIRect clip) const = 0;
#endif
    // This call is not thread safe. It should only be called from a known single-threaded env.
    virtual std::tuple<bool, int> regenerateAtlas(
            int begin, int end, RegenerateAtlasDelegate) const = 0;

    virtual const VertexFiller& vertexFiller() const = 0;

    virtual void testingOnly_packedGlyphIDToGlyph(StrikeCache* cache) const = 0;
};

using AtlasDrawDelegate = std::function<void(const sktext::gpu::AtlasSubRun* subRun,
                                             SkPoint drawOrigin,
                                             const SkPaint& paint,
                                             sk_sp<SkRefCnt> subRunStorage,
                                             sktext::gpu::RendererData)>;

// -- SubRun -------------------------------------------------------------------------------------
// SubRun defines the most basic functionality of a SubRun; the ability to draw, and the
// ability to be in a list.
class SubRun;
using SubRunOwner = std::unique_ptr<SubRun, SubRunAllocator::Destroyer>;
class SubRun {
public:
    virtual ~SubRun();

    virtual void draw(SkCanvas*, SkPoint drawOrigin, const SkPaint&, sk_sp<SkRefCnt> subRunStorage,
                      const AtlasDrawDelegate&) const = 0;

    void flatten(SkWriteBuffer& buffer) const;
    static SubRunOwner MakeFromBuffer(SkReadBuffer& buffer,
                                      sktext::gpu::SubRunAllocator* alloc,
                                      const SkStrikeClient* client);

    // Size hint for unflattening this run. If this is accurate, it will help with the allocation
    // of the slug. If it's off then there may be more allocations needed to unflatten.
    virtual int unflattenSize() const = 0;

    // Given an already cached subRun, can this subRun handle this combination paint, matrix, and
    // position.
    virtual bool canReuse(const SkPaint& paint, const SkMatrix& positionMatrix) const = 0;

    // Return the underlying atlas SubRun if it exists. Otherwise, return nullptr.
    // * Don't use this API. It is only to support testing.
    virtual const AtlasSubRun* testingOnly_atlasSubRun() const = 0;

protected:
    enum SubRunStreamTag : int;
    virtual SubRunStreamTag subRunStreamTag() const = 0;
    virtual void doFlatten(SkWriteBuffer& buffer) const = 0;

private:
    friend class SubRunList;
    SubRunOwner fNext;
};

// -- SubRunList -----------------------------------------------------------------------------------
class SubRunList {
public:
    class Iterator {
    public:
        using value_type = SubRun;
        using difference_type = ptrdiff_t;
        using pointer = value_type*;
        using reference = value_type&;
        using iterator_category = std::input_iterator_tag;
        Iterator(SubRun* subRun) : fPtr{subRun} { }
        Iterator& operator++() { fPtr = fPtr->fNext.get(); return *this; }
        Iterator operator++(int) { Iterator tmp(*this); operator++(); return tmp; }
        bool operator==(const Iterator& rhs) const { return fPtr == rhs.fPtr; }
        bool operator!=(const Iterator& rhs) const { return fPtr != rhs.fPtr; }
        reference operator*() { return *fPtr; }

    private:
        SubRun* fPtr;
    };

    void append(SubRunOwner subRun) {
        SubRunOwner* newTail = &subRun->fNext;
        *fTail = std::move(subRun);
        fTail = newTail;
    }
    bool isEmpty() const { return fHead == nullptr; }
    Iterator begin() { return Iterator{ fHead.get()}; }
    Iterator end() { return Iterator{nullptr}; }
    Iterator begin() const { return Iterator{ fHead.get()}; }
    Iterator end() const { return Iterator{nullptr}; }
    SubRun& front() const {return *fHead; }

private:
    SubRunOwner fHead{nullptr};
    SubRunOwner* fTail{&fHead};
};

// -- SubRunContainer ------------------------------------------------------------------------------
class SubRunContainer;
using SubRunContainerOwner = std::unique_ptr<SubRunContainer, SubRunAllocator::Destroyer>;
class SubRunContainer {
public:
    explicit SubRunContainer(const SkMatrix& initialPositionMatrix);
    SubRunContainer() = delete;
    SubRunContainer(const SubRunContainer&) = delete;
    SubRunContainer& operator=(const SubRunContainer&) = delete;

    // Delete the move operations because the SubRuns contain pointers to fInitialPositionMatrix.
    SubRunContainer(SubRunContainer&&) = delete;
    SubRunContainer& operator=(SubRunContainer&&) = delete;

    void flattenAllocSizeHint(SkWriteBuffer& buffer) const;
    static int AllocSizeHintFromBuffer(SkReadBuffer& buffer);

    void flattenRuns(SkWriteBuffer& buffer) const;
    static SubRunContainerOwner MakeFromBufferInAlloc(SkReadBuffer& buffer,
                                                      const SkStrikeClient* client,
                                                      SubRunAllocator* alloc);

    enum SubRunCreationBehavior {kAddSubRuns, kStrikeCalculationsOnly};
    // The returned SubRunContainerOwner will never be null. If subRunCreation ==
    // kStrikeCalculationsOnly, then the returned container will be empty.
    [[nodiscard]] static SubRunContainerOwner MakeInAlloc(const GlyphRunList& glyphRunList,
                                                          const SkMatrix& positionMatrix,
                                                          const SkPaint& runPaint,
                                                          SkStrikeDeviceInfo strikeDeviceInfo,
                                                          StrikeForGPUCacheInterface* strikeCache,
                                                          sktext::gpu::SubRunAllocator* alloc,
                                                          SubRunCreationBehavior creationBehavior,
                                                          const char* tag);

    static size_t EstimateAllocSize(const GlyphRunList& glyphRunList);

    void draw(SkCanvas*, SkPoint drawOrigin, const SkPaint&, const SkRefCnt* subRunStorage,
              const AtlasDrawDelegate&) const;

    const SkMatrix& initialPosition() const { return fInitialPositionMatrix; }
    bool isEmpty() const { return fSubRuns.isEmpty(); }
    bool canReuse(const SkPaint& paint, const SkMatrix& positionMatrix) const;

private:
    friend class TextBlobTools;
    const SkMatrix fInitialPositionMatrix;
    SubRunList fSubRuns;
};

// Returns the empty span if there is a problem reading the positions.
SkSpan<SkPoint> MakePointsFromBuffer(SkReadBuffer&, SubRunAllocator*);

}  // namespace sktext::gpu

#endif  // sktext_gpu_SubRunContainer_DEFINED
