/*
 * Copyright (C) 2011-2021 The Android Open Source Project
 *
 * 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 RENDER_DOC_H
#define RENDER_DOC_H

#include <renderdoc_app.h>

#include <algorithm>
#include <cstring>
#include <memory>
#include <mutex>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <vector>

#include "aemu/base/SharedLibrary.h"
#include "host-common/logging.h"
#include "vulkan/vulkan.h"

using android::base::SharedLibrary;

namespace emugl {
class RenderDoc {
   public:
    using RenderDocApi = RENDERDOC_API_1_4_2;
    static std::unique_ptr<RenderDoc> create(const SharedLibrary* renderDocLib) {
        if (!renderDocLib) {
            ERR("The renderdoc shared library is null.");
            return nullptr;
        }
        pRENDERDOC_GetAPI RENDERDOC_GetAPI =
            reinterpret_cast<pRENDERDOC_GetAPI>(renderDocLib->findSymbol("RENDERDOC_GetAPI"));
        if (!RENDERDOC_GetAPI) {
            ERR("Failed to find the RENDERDOC_GetAPI symbol.");
            return nullptr;
        }
        RenderDocApi* rdocApi = nullptr;
        int ret =
            RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_4_2, reinterpret_cast<void**>(&rdocApi));
        if (ret != 1 || rdocApi == nullptr) {
            ERR("Failed to load renderdoc API. %d is returned from RENDERDOC_GetAPI.");
            return nullptr;
        }
        return std::unique_ptr<RenderDoc>(new RenderDoc(rdocApi));
    }

    static constexpr auto kSetActiveWindow = &RenderDocApi::SetActiveWindow;
    static constexpr auto kGetCaptureOptionU32 = &RenderDocApi::GetCaptureOptionU32;
    static constexpr auto kIsFrameCapturing = &RenderDocApi::IsFrameCapturing;
    static constexpr auto kStartFrameCapture = &RenderDocApi::StartFrameCapture;
    static constexpr auto kEndFrameCapture = &RenderDocApi::EndFrameCapture;
    template <class F, class... Args, typename = std::enable_if_t<std::is_invocable_v<F, Args...>>>
    // Call a RenderDoc in-application API given the function pointer and parameters, and guard the
    // API call with a mutex.
    auto call(F(RenderDocApi::*function), Args... args) const {
        std::lock_guard<std::mutex> guard(mMutex);
        return (mRdocApi->*function)(args...);
    }

   private:
    RenderDoc(RenderDocApi* rdocApi) : mRdocApi(rdocApi) {}

    mutable std::mutex mMutex;
    RenderDocApi* mRdocApi = nullptr;
};

template <class RenderDocT>
class RenderDocWithMultipleVkInstancesBase {
   public:
    RenderDocWithMultipleVkInstancesBase(RenderDocT& renderDoc) : mRenderDoc(renderDoc) {}

    void onFrameDelimiter(VkInstance vkInstance) {
        std::lock_guard<std::mutex> guard(mMutex);
        mCaptureContexts.erase(vkInstance);
        if (mRenderDoc.call(RenderDoc::kIsFrameCapturing)) {
            mCaptureContexts.emplace(vkInstance,
                                     std::make_unique<CaptureContext>(mRenderDoc, vkInstance));
        }
    }

    void removeVkInstance(VkInstance vkInstance) {
        std::lock_guard<std::mutex> guard(mMutex);
        mCaptureContexts.erase(vkInstance);
    }

   private:
    class CaptureContext {
       public:
        CaptureContext(RenderDocT& renderDoc, VkInstance vkInstance)
            : mRenderDoc(renderDoc), mVkInstance(vkInstance) {
            mRenderDoc.call(RenderDoc::kStartFrameCapture,
                            RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(mVkInstance), nullptr);
        }
        ~CaptureContext() {
            mRenderDoc.call(RenderDoc::kEndFrameCapture,
                            RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(mVkInstance), nullptr);
        }

       private:
        const RenderDocT& mRenderDoc;
        const VkInstance mVkInstance;
    };
    std::mutex mMutex;
    std::unordered_map<VkInstance, std::unique_ptr<CaptureContext>> mCaptureContexts;
    RenderDocT& mRenderDoc;
};

using RenderDocWithMultipleVkInstances = RenderDocWithMultipleVkInstancesBase<RenderDoc>;
}  // namespace emugl

#endif
