// Copyright 2020 The Dawn 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
//
//     http://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.

#ifndef DAWNNATIVE_PERSISTENTCACHE_H_
#define DAWNNATIVE_PERSISTENTCACHE_H_

#include "dawn_native/Error.h"

#include <mutex>
#include <vector>

namespace dawn::platform {
    class CachingInterface;
}

namespace dawn::native {

    using PersistentCacheKey = std::vector<uint8_t>;

    struct ScopedCachedBlob {
        std::unique_ptr<uint8_t[]> buffer;
        size_t bufferSize = 0;
    };

    class DeviceBase;

    enum class PersistentKeyType { Shader };

    // This class should always be thread-safe as it is used in Create*PipelineAsync() where it is
    // called asynchronously.
    // The thread-safety of any access to mCache (the function LoadData() and StoreData()) is
    // protected by mMutex.
    class PersistentCache {
      public:
        PersistentCache(DeviceBase* device);

        // Combines load/store operations into a single call.
        // If the load was successful, a non-empty blob is returned to the caller.
        // Else, the creation callback |createFn| gets invoked with a callback
        // |doCache| to store the newly created blob back in the cache.
        //
        // Example usage:
        //
        // ScopedCachedBlob cachedBlob = {};
        // DAWN_TRY_ASSIGN(cachedBlob, GetOrCreate(key, [&](auto doCache)) {
        //      // Create a new blob to be stored
        //      doCache(newBlobPtr, newBlobSize); // store
        // }));
        //
        template <typename CreateFn>
        ResultOrError<ScopedCachedBlob> GetOrCreate(const PersistentCacheKey& key,
                                                    CreateFn&& createFn) {
            // Attempt to load an existing blob from the cache.
            ScopedCachedBlob blob = LoadData(key);
            if (blob.bufferSize > 0) {
                return std::move(blob);
            }

            // Allow the caller to create a new blob to be stored for the given key.
            DAWN_TRY(createFn([this, key](const void* value, size_t size) {
                this->StoreData(key, value, size);
            }));

            return std::move(blob);
        }

      private:
        // PersistentCache impl
        ScopedCachedBlob LoadData(const PersistentCacheKey& key);
        void StoreData(const PersistentCacheKey& key, const void* value, size_t size);

        dawn::platform::CachingInterface* GetPlatformCache();

        DeviceBase* mDevice = nullptr;

        std::mutex mMutex;
        dawn::platform::CachingInterface* mCache = nullptr;
    };
}  // namespace dawn::native

#endif  // DAWNNATIVE_PERSISTENTCACHE_H_
