/*
 * Copyright 2022 Rive
 */

#ifndef TESTING_WINDOW_HPP
#define TESTING_WINDOW_HPP

#include "rive/rive_types.hpp"
#include "rive/enum_bitset.hpp"
#include <memory>
#include <vector>
#include <string>

namespace rive
{
class Renderer;
class Factory;
namespace gpu
{
class RenderContext;
class RenderContextGLImpl;
class RenderTarget;
} // namespace gpu
}; // namespace rive

// Wraps a factory for rive::Renderer and a singleton target for it to render
// into (GL window, HTML canvas, software buffer, etc.):
//
//   TestingWindow::Init(type);
//   renderer = TestingWindow::Get()->reset(width, height);
//   ...
//

class TestingWindow
{
public:
    enum class Backend
    {
        gl,
        glatomic,
        glcw,
        glmsaa,
        d3d,
        d3datomic,
        metal,
        metalcw,
        metalatomic,

        // System default Vulkan driver.
        vk,
        vkcore, // Vulkan with as few features enabled as possible.
        vkcw,

        // Vulkan on Metal, aka MoltenVK.
        // (defaults to /usr/local/share/vulkan/icd.d/MoltenVK_icd.json if
        // VK_ICD_FILENAMES is not set.)
        moltenvk,
        moltenvkcore,

        // Swiftshader, Google's CPU implementation of Vulkan.
        // (defaults to ./vk_swiftshader_icd.json if VK_ICD_FILENAMES is not
        // set.)
        swiftshader,
        swiftshadercore,

        angle,
        anglemsaa,
        dawn,

        rhi,

        coregraphics,
        skia,
    };

    constexpr static bool IsGL(Backend backend)
    {
        switch (backend)
        {
            case Backend::gl:
            case Backend::glatomic:
            case Backend::glcw:
            case Backend::glmsaa:
            case Backend::angle:
            case Backend::anglemsaa:
                return true;
            case Backend::d3d:
            case Backend::d3datomic:
            case Backend::metal:
            case Backend::metalcw:
            case Backend::metalatomic:
            case Backend::vk:
            case Backend::vkcore:
            case Backend::vkcw:
            case Backend::moltenvk:
            case Backend::moltenvkcore:
            case Backend::swiftshader:
            case Backend::swiftshadercore:
            case Backend::dawn:
            case Backend::rhi:
            case Backend::coregraphics:
            case Backend::skia:
                return false;
        }
        RIVE_UNREACHABLE();
    }

    constexpr static bool IsANGLE(Backend backend)
    {
        switch (backend)
        {
            case Backend::angle:
            case Backend::anglemsaa:
                return true;
            case Backend::gl:
            case Backend::glatomic:
            case Backend::glcw:
            case Backend::glmsaa:
            case Backend::d3d:
            case Backend::d3datomic:
            case Backend::metal:
            case Backend::metalcw:
            case Backend::metalatomic:
            case Backend::vk:
            case Backend::vkcore:
            case Backend::vkcw:
            case Backend::moltenvk:
            case Backend::moltenvkcore:
            case Backend::swiftshader:
            case Backend::swiftshadercore:
            case Backend::dawn:
            case Backend::rhi:
            case Backend::coregraphics:
            case Backend::skia:
                return false;
        }
        RIVE_UNREACHABLE();
    }

    constexpr static bool IsVulkan(Backend backend)
    {
        switch (backend)
        {
            case Backend::vk:
            case Backend::vkcore:
            case Backend::vkcw:
            case Backend::moltenvk:
            case Backend::moltenvkcore:
            case Backend::swiftshader:
            case Backend::swiftshadercore:
                return true;
            case Backend::gl:
            case Backend::glatomic:
            case Backend::glcw:
            case Backend::glmsaa:
            case Backend::d3d:
            case Backend::d3datomic:
            case Backend::metal:
            case Backend::metalcw:
            case Backend::metalatomic:
            case Backend::dawn:
            case Backend::angle:
            case Backend::anglemsaa:
            case Backend::rhi:
            case Backend::coregraphics:
            case Backend::skia:
                return false;
        }
        RIVE_UNREACHABLE();
    }

    constexpr static bool IsAtomic(Backend backend)
    {
        switch (backend)
        {
            case Backend::glatomic:
            case Backend::glcw:
            case Backend::d3datomic:
            case Backend::metalatomic:
            case Backend::rhi:
            case Backend::vkcore:
            case Backend::vkcw:
            case Backend::moltenvkcore:
            case Backend::swiftshadercore:
                return true;
            case Backend::gl:
            case Backend::glmsaa:
            case Backend::d3d:
            case Backend::metal:
            case Backend::metalcw:
            case Backend::vk:
            case Backend::moltenvk:
            case Backend::swiftshader:
            case Backend::angle:
            case Backend::anglemsaa:
            case Backend::dawn:
            case Backend::coregraphics:
            case Backend::skia:
                return false;
        }
        RIVE_UNREACHABLE();
    }

    constexpr static bool IsCore(Backend backend)
    {
        switch (backend)
        {
            case Backend::vkcore:
            case Backend::moltenvkcore:
            case Backend::swiftshadercore:
                return true;
            case Backend::glatomic:
            case Backend::glcw:
            case Backend::d3datomic:
            case Backend::metalatomic:
            case Backend::gl:
            case Backend::glmsaa:
            case Backend::d3d:
            case Backend::metal:
            case Backend::metalcw:
            case Backend::vk:
            case Backend::vkcw:
            case Backend::moltenvk:
            case Backend::swiftshader:
            case Backend::angle:
            case Backend::anglemsaa:
            case Backend::dawn:
            case Backend::rhi:
            case Backend::coregraphics:
            case Backend::skia:
                return false;
        }
        RIVE_UNREACHABLE();
    }

    constexpr static bool IsMSAA(Backend backend)
    {
        switch (backend)
        {
            case Backend::glmsaa:
            case Backend::anglemsaa:
                return true;
            case Backend::glatomic:
            case Backend::glcw:
            case Backend::d3datomic:
            case Backend::metalatomic:
            case Backend::vkcore:
            case Backend::vkcw:
            case Backend::moltenvkcore:
            case Backend::swiftshadercore:
            case Backend::gl:
            case Backend::d3d:
            case Backend::metal:
            case Backend::metalcw:
            case Backend::vk:
            case Backend::moltenvk:
            case Backend::swiftshader:
            case Backend::angle:
            case Backend::dawn:
            case Backend::rhi:
            case Backend::coregraphics:
            case Backend::skia:
                return false;
        }
        RIVE_UNREACHABLE();
    }

    constexpr static bool IsClockwiseFill(Backend backend)
    {
        switch (backend)
        {
            case Backend::glcw:
            case Backend::metalcw:
            case Backend::vkcw:
                return true;
            case Backend::glatomic:
            case Backend::glmsaa:
            case Backend::d3datomic:
            case Backend::metalatomic:
            case Backend::vkcore:
            case Backend::moltenvkcore:
            case Backend::swiftshadercore:
            case Backend::gl:
            case Backend::d3d:
            case Backend::metal:
            case Backend::vk:
            case Backend::moltenvk:
            case Backend::swiftshader:
            case Backend::angle:
            case Backend::anglemsaa:
            case Backend::dawn:
            case Backend::rhi:
            case Backend::coregraphics:
            case Backend::skia:
                return false;
        }
        RIVE_UNREACHABLE();
    }

    enum class RendererFlags
    {
        none = 0,
        useMSAA = 1 << 0,
        disableRasterOrdering = 1 << 1,
        clockwiseFillOverride = 1 << 2,
    };

    enum class Visibility
    {
        headless,
        window,
        fullscreen,
    };

    static const char* BackendName(Backend);
    static Backend ParseBackend(const char* name, std::string* gpuNameFilter);
    static TestingWindow* Init(Backend,
                               Visibility,
                               const std::string& gpuNameFilter,
                               void* platformWindow = nullptr);
    static TestingWindow* Get();
    static void Set(TestingWindow* inWindow);
    static void Destroy();

    uint32_t width() const { return m_width; }
    uint32_t height() const { return m_height; }

    virtual rive::Factory* factory() = 0;
    virtual void resize(int width, int height)
    {
        m_width = width;
        m_height = height;
    }
    struct FrameOptions
    {
        uint32_t clearColor;
        bool doClear = true;
        bool wireframe = false;
        bool clockwiseFillOverride = false;
    };
    virtual std::unique_ptr<rive::Renderer> beginFrame(const FrameOptions&) = 0;
    virtual void endFrame(std::vector<uint8_t>* pixelData = nullptr) = 0;

    // For testing directly on RenderContext.
    virtual rive::gpu::RenderContext* renderContext() const { return nullptr; }
    virtual rive::gpu::RenderContextGLImpl* renderContextGLImpl() const
    {
        return nullptr;
    }
    virtual rive::gpu::RenderTarget* renderTarget() const { return nullptr; }

    // For testing render pass breaks. Caller must call
    // renderContext()->beginFrame() again.
    virtual void flushPLSContext() {}

    // Blocks until a key is pressed.
    virtual bool peekKey(char& key) { return false; }
    virtual char getKey()
    {
        fprintf(stderr, "TestingWindow::getKey not implemented.");
        abort();
    }
    virtual bool shouldQuit() const { return false; }

    virtual ~TestingWindow() {}

protected:
    uint32_t m_width = 0;
    uint32_t m_height = 0;

private:
    static TestingWindow* MakeGLFW(Backend, Visibility);
    static TestingWindow* MakeEGL(Backend, void* platformWindow);
#ifdef _WIN32
    static TestingWindow* MakeD3D(Visibility);
#endif
#if defined(__APPLE__) && !defined(RIVE_UNREAL)
    static TestingWindow* MakeMetalTexture();
#endif
    static TestingWindow* MakeCoreGraphics();
    static TestingWindow* MakeFiddleContext(Backend,
                                            Visibility,
                                            const char* gpuNameFilter,
                                            void* platformWindow);
    static TestingWindow* MakeVulkanTexture(bool coreFeaturesOnly,
                                            bool clockwiseFill,
                                            const char* gpuNameFilter);
    static TestingWindow* MakeAndroidVulkan(void* platformWindow,
                                            bool coreFeaturesOnly,
                                            bool clockwiseFill);
    static TestingWindow* MakeSkia();
};

RIVE_MAKE_ENUM_BITSET(TestingWindow::RendererFlags);

#endif
