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

#ifndef SkRemoteGlyphCache_DEFINED
#define SkRemoteGlyphCache_DEFINED

// Use `extra_cflags=["-DSK_CAPTURE_DRAW_TEXT_BLOB"]` to capture traces to disc.

// Or uncomment this line:
//#define SK_CAPTURE_DRAW_TEXT_BLOB

#include <memory>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include "include/core/SkData.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSerialProcs.h"
#include "include/core/SkTypeface.h"
#include "include/private/SkTHash.h"
#include "include/utils/SkNoDrawCanvas.h"
#include "src/core/SkDevice.h"
#include "src/core/SkStrikeForGPU.h"
#include "src/core/SkTLazy.h"
#include "src/core/SkTextBlobTrace.h"

class Deserializer;
class Serializer;
enum SkAxisAlignment : uint32_t;
class SkDescriptor;
class SkAutoDescriptor;
struct SkPackedGlyphID;
enum SkScalerContextFlags : uint32_t;
class SkStrikeCache;
class SkTypefaceProxy;
struct WireTypeface;

class SkStrikeServer;

// A SkTextBlobCacheDiffCanvas is used to populate the SkStrikeServer with ops
// which will be serialized and rendered using the SkStrikeClient.
class SkTextBlobCacheDiffCanvas : public SkNoDrawCanvas {
public:

    // For testing use only
    SkTextBlobCacheDiffCanvas(int width, int height, const SkSurfaceProps& props,
                              SkStrikeServer* strikeServer, bool DFTSupport = true);

    SK_SPI SkTextBlobCacheDiffCanvas(int width, int height, const SkSurfaceProps& props,
                                     SkStrikeServer* strikeServer, sk_sp<SkColorSpace> colorSpace,
                                     bool DFTSupport);

    SK_SPI ~SkTextBlobCacheDiffCanvas() override;

protected:
    SkCanvas::SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& rec) override;
    bool onDoSaveBehind(const SkRect*) override;
    void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
                        const SkPaint& paint) override;

private:
    class TrackLayerDevice;
};

using SkDiscardableHandleId = uint32_t;

// This class is not thread-safe.
class SkStrikeServer final : public SkStrikeForGPUCacheInterface {
public:
    // An interface used by the server to create handles for pinning SkStrike
    // entries on the remote client.
    class DiscardableHandleManager {
    public:
        SK_SPI virtual ~DiscardableHandleManager() = default;

        // Creates a new *locked* handle and returns a unique ID that can be used to identify
        // it on the remote client.
        SK_SPI virtual SkDiscardableHandleId createHandle() = 0;

        // Returns true if the handle could be successfully locked. The server can
        // assume it will remain locked until the next set of serialized entries is
        // pulled from the SkStrikeServer.
        // If returns false, the cache entry mapped to the handle has been deleted
        // on the client. Any subsequent attempts to lock the same handle are not
        // allowed.
        SK_SPI virtual bool lockHandle(SkDiscardableHandleId) = 0;

        // Returns true if a handle has been deleted on the remote client. It is
        // invalid to use a handle id again with this manager once this returns true.
        // TODO(khushalsagar): Make pure virtual once chrome implementation lands.
        SK_SPI virtual bool isHandleDeleted(SkDiscardableHandleId) { return false; }
    };

    SK_SPI explicit SkStrikeServer(DiscardableHandleManager* discardableHandleManager);
    SK_SPI ~SkStrikeServer() override;

    // Serializes the typeface to be transmitted using this server.
    SK_SPI sk_sp<SkData> serializeTypeface(SkTypeface*);

    // Serializes the strike data captured using a SkTextBlobCacheDiffCanvas. Any
    // handles locked using the DiscardableHandleManager will be assumed to be
    // unlocked after this call.
    SK_SPI void writeStrikeData(std::vector<uint8_t>* memory);

    // Methods used internally in Skia ------------------------------------------
    class RemoteStrike;

    RemoteStrike* getOrCreateCache(const SkPaint&,
                                   const SkFont& font,
                                   const SkSurfaceProps&,
                                   const SkMatrix&,
                                   SkScalerContextFlags flags,
                                   SkScalerContextEffects* effects);

    SkScopedStrikeForGPU findOrCreateScopedStrike(const SkDescriptor& desc,
                                                  const SkScalerContextEffects& effects,
                                                  const SkTypeface& typeface) override;

    static void AddGlyphForTesting(
            RemoteStrike* strike, SkDrawableGlyphBuffer* drawables, SkSourceGlyphBuffer* rejects);

    void setMaxEntriesInDescriptorMapForTesting(size_t count) {
        fMaxEntriesInDescriptorMap = count;
    }
    size_t remoteStrikeMapSizeForTesting() const { return fDescToRemoteStrike.size(); }

    #ifdef SK_CAPTURE_DRAW_TEXT_BLOB
    // DrawTextBlob trace capture.
    std::unique_ptr<SkTextBlobTrace::Capture> fCapture;
    #endif  //  SK_CAPTURE_DRAW_TEXT_BLOB

private:
    static constexpr size_t kMaxEntriesInDescriptorMap = 2000u;

    void checkForDeletedEntries();

    RemoteStrike* getOrCreateCache(const SkDescriptor& desc,
                                   const SkTypeface& typeface,
                                   SkScalerContextEffects effects);

    struct MapOps {
        size_t operator()(const SkDescriptor* key) const;
        bool operator()(const SkDescriptor* lhs, const SkDescriptor* rhs) const;
    };
    using DescToRemoteStrike =
            std::unordered_map<const SkDescriptor*, std::unique_ptr<RemoteStrike>, MapOps, MapOps>;
    DescToRemoteStrike fDescToRemoteStrike;

    DiscardableHandleManager* const fDiscardableHandleManager;
    SkTHashSet<SkFontID> fCachedTypefaces;
    size_t fMaxEntriesInDescriptorMap = kMaxEntriesInDescriptorMap;

    // Cached serialized typefaces.
    SkTHashMap<SkFontID, sk_sp<SkData>> fSerializedTypefaces;

    // State cached until the next serialization.
    SkTHashSet<RemoteStrike*> fRemoteStrikesToSend;
    std::vector<WireTypeface> fTypefacesToSend;
};

class SkStrikeClient {
public:
    // This enum is used in histogram reporting in chromium. Please don't re-order the list of
    // entries, and consider it to be append-only.
    enum CacheMissType : uint32_t {
        // Hard failures where no fallback could be found.
        kFontMetrics = 0,
        kGlyphMetrics = 1,
        kGlyphImage = 2,
        kGlyphPath = 3,

        // (DEPRECATED) The original glyph could not be found and a fallback was used.
        kGlyphMetricsFallback = 4,
        kGlyphPathFallback = 5,

        kLast = kGlyphPath
    };

    // An interface to delete handles that may be pinned by the remote server.
    class DiscardableHandleManager : public SkRefCnt {
    public:
        ~DiscardableHandleManager() override = default;

        // Returns true if the handle was unlocked and can be safely deleted. Once
        // successful, subsequent attempts to delete the same handle are invalid.
        virtual bool deleteHandle(SkDiscardableHandleId) = 0;

        virtual void notifyCacheMiss(CacheMissType) {}

        struct ReadFailureData {
            size_t memorySize;
            size_t bytesRead;
            uint64_t typefaceSize;
            uint64_t strikeCount;
            uint64_t glyphImagesCount;
            uint64_t glyphPathsCount;
        };
        virtual void notifyReadFailure(const ReadFailureData& data) {}
    };

    SK_SPI explicit SkStrikeClient(sk_sp<DiscardableHandleManager>,
                                   bool isLogging = true,
                                   SkStrikeCache* strikeCache = nullptr);
    SK_SPI ~SkStrikeClient();

    // Deserializes the typeface previously serialized using the SkStrikeServer. Returns null if the
    // data is invalid.
    SK_SPI sk_sp<SkTypeface> deserializeTypeface(const void* data, size_t length);

    // Deserializes the strike data from a SkStrikeServer. All messages generated
    // from a server when serializing the ops must be deserialized before the op
    // is rasterized.
    // Returns false if the data is invalid.
    SK_SPI bool readStrikeData(const volatile void* memory, size_t memorySize);

private:
    class DiscardableStrikePinner;

    static bool ReadGlyph(SkTLazy<SkGlyph>& glyph, Deserializer* deserializer);
    sk_sp<SkTypeface> addTypeface(const WireTypeface& wire);

    SkTHashMap<SkFontID, sk_sp<SkTypeface>> fRemoteFontIdToTypeface;
    sk_sp<DiscardableHandleManager> fDiscardableHandleManager;
    SkStrikeCache* const fStrikeCache;
    const bool fIsLogging;
};

// For exposure to fuzzing only.
bool SkFuzzDeserializeSkDescriptor(sk_sp<SkData> bytes, SkAutoDescriptor* ad);

#endif  // SkRemoteGlyphCache_DEFINED
