/*
 * 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 MemoryCache_DEFINED
#define MemoryCache_DEFINED

#include "include/core/SkData.h"
#include "include/gpu/GrContextOptions.h"
#include "src/core/SkChecksum.h"

#include <unordered_map>

namespace sk_gpu_test {

/**
 * This class can be used to maintain an in memory record of all programs cached by GrContext.
 * It can be shared by multiple GrContexts so long as those GrContexts are created with the same
 * options and will have the same GrCaps (e.g. same backend, same GL context creation parameters,
 * ...).
 */
class MemoryCache : public GrContextOptions::PersistentCache {
public:
    MemoryCache() = default;
    MemoryCache(const MemoryCache&) = delete;
    MemoryCache& operator=(const MemoryCache&) = delete;
    void reset() {
        this->resetCacheStats();
        fMap.clear();
    }

    sk_sp<SkData> load(const SkData& key) override;
    void store(const SkData& key, const SkData& data, const SkString& description) override;
    int numCacheMisses() const { return fCacheMissCnt; }
    int numCacheStores() const { return fCacheStoreCnt; }
    void resetCacheStats() {
        fCacheMissCnt = 0;
        fCacheStoreCnt = 0;
    }

    void writeShadersToDisk(const char* path, GrBackendApi backend);

    template <typename Fn>
    void foreach(Fn&& fn) {
        for (auto it = fMap.begin(); it != fMap.end(); ++it) {
            fn(it->first.fKey, it->second.fData, it->second.fDescription, it->second.fHitCount);
        }
    }

private:
    struct Key {
        Key() = default;
        Key(const SkData& key) : fKey(SkData::MakeWithCopy(key.data(), key.size())) {}
        Key(const Key& that) = default;
        Key& operator=(const Key&) = default;
        bool operator==(const Key& that) const {
            return that.fKey->size() == fKey->size() &&
                   !memcmp(fKey->data(), that.fKey->data(), that.fKey->size());
        }
        sk_sp<const SkData> fKey;
    };

    struct Value {
        Value() = default;
        Value(const SkData& data, const SkString& description)
            : fData(SkData::MakeWithCopy(data.data(), data.size()))
            , fDescription(description)
            , fHitCount(1) {}
        Value(const Value& that) = default;
        Value& operator=(const Value&) = default;

        sk_sp<SkData> fData;
        SkString      fDescription;
        int           fHitCount;
    };

    struct Hash {
        using argument_type = Key;
        using result_type = uint32_t;
        uint32_t operator()(const Key& key) const {
            return key.fKey ? SkChecksum::Hash32(key.fKey->data(), key.fKey->size()) : 0;
        }
    };

    int fCacheMissCnt = 0;
    int fCacheStoreCnt = 0;
    std::unordered_map<Key, Value, Hash> fMap;
};

}  // namespace sk_gpu_test

#endif
