/*
 * Copyright 2025 Rive
 */

#pragma once

#include "rive/object_stream.hpp"
#include "rive/refcnt.hpp"
#include "rive/math/vec2d.hpp"
#include "rive/viewmodel/runtime/viewmodel_runtime.hpp"
#include "rive/animation/semantic_listener_group.hpp"
#include "rive/semantic/semantic_snapshot.hpp"

#include <condition_variable>
#include <cstdint>
#include <functional>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
#include <unordered_map>
#include "file_asset_loader.hpp"

// Macros for defining and working with command buffer handles.
#if INTPTR_MAX == INT64_MAX
static_assert(sizeof(void*) == 8, "expected a 64-bit environment");
// Define handles as pointers to forward-declared types for type safety.
#define RIVE_DEFINE_HANDLE(NAME) using NAME = struct NAME##_HandlePlaceholder*;
#define RIVE_NULL_HANDLE nullptr
#elif INTPTR_MAX == INT32_MAX
static_assert(sizeof(void*) == 4, "expected a 32-bit environment");
#define RIVE_DEFINE_HANDLE(NAME) using NAME = uint64_t;
#define RIVE_NULL_HANDLE 0
#else
#error "environment not 32 or 64-bit."
#endif

namespace rive
{
class Factory;
class File;
class ArtboardInstance;
class StateMachineInstance;
class CommandServer;
class ScriptingContext;

RIVE_DEFINE_HANDLE(FontHandle);
RIVE_DEFINE_HANDLE(FileHandle);
RIVE_DEFINE_HANDLE(ArtboardHandle);
RIVE_DEFINE_HANDLE(AudioSourceHandle);
RIVE_DEFINE_HANDLE(RenderImageHandle);
RIVE_DEFINE_HANDLE(BlobAssetHandle);
RIVE_DEFINE_HANDLE(StateMachineHandle);
RIVE_DEFINE_HANDLE(ViewModelInstanceHandle);
RIVE_DEFINE_HANDLE(DrawKey);

// Function poimter that gets called back from the server thread.
using CommandServerCallback = std::function<void(CommandServer*)>;
using CommandServerDrawCallback = std::function<void(DrawKey, CommandServer*)>;

// Creates the ScriptingContext used for a loaded file's Lua VM. Invoked on the
// command server thread with the server's Factory so the context is built with
// the correct factory on the correct thread. Return nullptr (or leave the
// factory empty) to fall back to the default CPPRuntimeScriptingContext. Used
// by hosts (e.g. Unreal) to redirect Lua console/error output to their own
// logging.
using ScriptingContextFactory =
    std::function<std::unique_ptr<ScriptingContext>(Factory*)>;

struct ViewModelEnum
{
    std::string name;
    std::vector<std::string> enumerants;
};

// Client-side recorder for commands that will be executed by a CommandServer.
// Synchronized operations require an active CommandServer processing this
// queue on another thread and must not be called after disconnect(); otherwise,
// they block indefinitely.
class CommandQueue : public RefCnt<CommandQueue>
{
public:
    template <typename ListenerType, typename HandleType> class ListenerBase
    {
    public:
        friend class CommandQueue;

        ListenerBase(const ListenerBase&) = delete;
        ListenerBase& operator=(const ListenerBase&) = delete;
        ListenerBase(ListenerBase&& other) :
            m_owningQueue(std::move(other.m_owningQueue)),
            m_handle(std::move(other.m_handle))
        {
            if (m_owningQueue)
            {
                m_owningQueue->unregisterListener(
                    m_handle,
                    static_cast<ListenerType*>(&other));
                m_owningQueue->registerListener(
                    m_handle,
                    static_cast<ListenerType*>(this));
            }
        }
        ~ListenerBase()
        {
            if (m_owningQueue)
                m_owningQueue->unregisterListener(
                    m_handle,
                    static_cast<ListenerType*>(this));
        }
        ListenerBase() : m_handle(RIVE_NULL_HANDLE) {}

    private:
        rcp<CommandQueue> m_owningQueue;
        HandleType m_handle;
    };

    class FileListener
        : public CommandQueue::ListenerBase<FileListener, FileHandle>
    {
    public:
        virtual void onFileError(const FileHandle,
                                 uint64_t requestId,
                                 std::string error)
        {}

        virtual void onFileDeleted(const FileHandle, uint64_t requestId) {}

        virtual void onFileLoaded(const FileHandle, uint64_t requestId) {}

        /**
         * Called after an artboard instance is created.
         *
         * @param fileHandle The file from which the artboard was instantiated.
         * @param requestId The request that created the artboard handle.
         * @param artboardHandle The confirmed artboard handle.
         */
        virtual void onArtboardInstantiated(const FileHandle fileHandle,
                                            uint64_t requestId,
                                            ArtboardHandle artboardHandle)
        {}

        /**
         * Called after a view model instance or instance reference is created.
         *
         * @param fileHandle The source file for a newly instantiated view
         * model, or RIVE_NULL_HANDLE when the new handle references an existing
         * nested or list-item instance. Confirmations with RIVE_NULL_HANDLE are
         * delivered only to a FileListener registered for RIVE_NULL_HANDLE.
         * @param requestId The request that created the instance handle.
         * @param viewModelInstanceHandle The confirmed instance handle.
         */
        virtual void onViewModelInstanceInstantiated(
            const FileHandle fileHandle,
            uint64_t requestId,
            ViewModelInstanceHandle viewModelInstanceHandle)
        {}

        virtual void onArtboardsListed(const FileHandle,
                                       uint64_t requestId,
                                       std::vector<std::string> artboardNames)
        {}

        virtual void onViewModelsListed(const FileHandle,
                                        uint64_t requestId,
                                        std::vector<std::string> viewModelNames)
        {}

        virtual void onGlobalViewModelNamesListed(
            const FileHandle,
            uint64_t requestId,
            std::vector<std::string> globalViewModelNames)
        {}

        virtual void onViewModelInstanceNamesListed(
            const FileHandle,
            uint64_t requestId,
            std::string viewModelName,
            std::vector<std::string> instanceNames)
        {}

        struct ViewModelPropertyData
        {
            DataType type = DataType::none;
            std::string name = "";
            std::string metaData = "";
        };

        virtual void onViewModelPropertiesListed(
            const FileHandle,
            uint64_t requestId,
            std::string viewModelName,
            std::vector<ViewModelPropertyData> properties)
        {}

        virtual void onViewModelEnumsListed(const FileHandle,
                                            uint64_t requestId,
                                            std::vector<ViewModelEnum> enums)
        {}

        struct FileAssetData
        {
            std::string name;
            std::string uniqueName;
            uint32_t assetID = 0;
            std::string cdnUUID;
            std::string cdnBaseURL;
            std::string fileExtension;
            uint16_t type = 0;
        };

        virtual void onFileAssetsListed(const FileHandle,
                                        uint64_t requestId,
                                        std::vector<FileAssetData> assets)
        {}
    };

    class RenderImageListener
        : public CommandQueue::ListenerBase<RenderImageListener,
                                            RenderImageHandle>
    {
    public:
        virtual void onRenderImageDecoded(const RenderImageHandle,
                                          uint64_t requestId)
        {}

        virtual void onRenderImageError(const RenderImageHandle,
                                        uint64_t requestId,
                                        std::string error)
        {}

        virtual void onRenderImageDeleted(const RenderImageHandle,
                                          uint64_t requestId)
        {}
    };

    class AudioSourceListener
        : public CommandQueue::ListenerBase<AudioSourceListener,
                                            AudioSourceHandle>
    {
    public:
        virtual void onAudioSourceDecoded(const AudioSourceHandle,
                                          uint64_t requestId)
        {}

        virtual void onAudioSourceError(const AudioSourceHandle,
                                        uint64_t requestId,
                                        std::string error)
        {}

        virtual void onAudioSourceDeleted(const AudioSourceHandle,
                                          uint64_t requestId)
        {}
    };

    class FontListener
        : public CommandQueue::ListenerBase<FontListener, FontHandle>
    {
    public:
        virtual void onFontDecoded(const FontHandle, uint64_t requestId) {}

        virtual void onFontError(const FontHandle,
                                 uint64_t requestId,
                                 std::string error)
        {}

        virtual void onFontDeleted(const FontHandle, uint64_t requestId) {}
    };

    class BlobAssetListener
        : public CommandQueue::ListenerBase<BlobAssetListener, BlobAssetHandle>
    {
    public:
        virtual void onBlobAssetDecoded(const BlobAssetHandle,
                                        uint64_t requestId)
        {}

        virtual void onBlobAssetError(const BlobAssetHandle,
                                      uint64_t requestId,
                                      std::string error)
        {}

        virtual void onBlobAssetDeleted(const BlobAssetHandle,
                                        uint64_t requestId)
        {}
    };

    class ArtboardListener
        : public CommandQueue::ListenerBase<ArtboardListener, ArtboardHandle>
    {
    public:
        virtual void onArtboardError(const ArtboardHandle,
                                     uint64_t requestId,
                                     std::string error)
        {}

        virtual void onDefaultViewModelInfoReceived(const ArtboardHandle,
                                                    uint64_t requestId,
                                                    std::string viewModelName,
                                                    std::string instanceName)
        {}

        virtual void onArtboardDeleted(const ArtboardHandle, uint64_t requestId)
        {}

        /**
         * Called after a state machine instance is created.
         *
         * @param artboardHandle The artboard from which the state machine was
         * instantiated.
         * @param requestId The request that created the state machine handle.
         * @param stateMachineHandle The confirmed state machine handle.
         */
        virtual void onStateMachineInstantiated(
            const ArtboardHandle artboardHandle,
            uint64_t requestId,
            StateMachineHandle stateMachineHandle)
        {}

        virtual void onStateMachinesListed(
            const ArtboardHandle,
            uint64_t requestId,
            std::vector<std::string> stateMachineNames)
        {}

        virtual void onArtboardVolumeReceived(const ArtboardHandle,
                                              uint64_t requestId,
                                              float volume)
        {}

        virtual void onArtboardSizeReceived(const ArtboardHandle,
                                            uint64_t requestId,
                                            float width,
                                            float height)
        {}
    };

    struct ViewModelInstanceData
    {
        // The path and type of this property
        PropertyData metaData;

        // The specific value of this property, you must use the correct union
        // member base on type in metaData, both enumType and string use
        // stringValue

        // std::string is non trival, so it stays outside the union
        std::string stringValue;
        union
        {
            bool boolValue;
            float numberValue;
            ColorInt colorValue;
        };
    };

    // Mirrors StateMachineInstance::FocusState for command queue responses.
    struct FocusState
    {
        bool hasFocus = false;
        bool expectsKeyboardInput = false;
    };

    class ViewModelInstanceListener
        : public CommandQueue::ListenerBase<ViewModelInstanceListener,
                                            ViewModelInstanceHandle>
    {
    public:
        virtual void onViewModelInstanceError(const ViewModelInstanceHandle,
                                              uint64_t requestId,
                                              std::string error)
        {}

        virtual void onViewModelInstanceViewModelNameReceived(
            const ViewModelInstanceHandle,
            uint64_t requestId,
            std::string viewModelName)
        {}
        virtual void onViewModelInstanceNameReceived(
            const ViewModelInstanceHandle handle,
            uint64_t requestId,
            std::string instanceName)
        {}

        virtual void onViewModelDeleted(const ViewModelInstanceHandle,
                                        uint64_t requestId)
        {}

        virtual void onViewModelDataReceived(const ViewModelInstanceHandle,
                                             uint64_t requestId,
                                             ViewModelInstanceData)
        {}

        virtual void onViewModelListSizeReceived(const ViewModelInstanceHandle,
                                                 uint64_t requestId,
                                                 std::string path,
                                                 size_t size)
        {}

        virtual void onViewModelListCleared(const ViewModelInstanceHandle,
                                            uint64_t requestId,
                                            std::string path)
        {}
    };

    class StateMachineListener
        : public CommandQueue::ListenerBase<StateMachineListener,
                                            StateMachineHandle>
    {
    public:
        virtual void onStateMachineError(const StateMachineHandle,
                                         uint64_t requestId,
                                         std::string error)
        {}

        virtual void onStateMachineDeleted(const StateMachineHandle,
                                           uint64_t requestId)
        {}
        // requestId in this case is the specific request that caused the
        // statemachine to settle
        virtual void onStateMachineSettled(const StateMachineHandle,
                                           uint64_t requestId)
        {}

        // Delivered when an incremental semantic diff is available for this
        // state machine. Emitted only when drainSemanticsDiff produces a
        // non-empty diff. Bounds inside the diff are reported in view space
        // using the fit/alignment/scale/view-bounds arguments provided to the
        // drain command.
        virtual void onSemanticsDiffReceived(const StateMachineHandle,
                                             uint64_t requestId,
                                             SemanticsDiff diff)
        {}

        virtual void onHasFocusNodesReceived(const StateMachineHandle,
                                             uint64_t requestId,
                                             bool hasFocusNodes)
        {}

        virtual void onFocusStateReceived(const StateMachineHandle,
                                          uint64_t requestId,
                                          FocusState focusState)
        {}
    };

    CommandQueue();
    ~CommandQueue();

    FileHandle loadFile(
        std::vector<uint8_t> rivBytes,
        FileListener* listener = nullptr,
        uint64_t requestId = 0
#ifdef WITH_RIVE_SCRIPTING
        ,
        ScriptingContextFactory scriptingContextFactory = nullptr
#endif
    );

    void deleteFile(FileHandle, uint64_t requestId = 0);

    void addGlobalImageAsset(std::string name,
                             RenderImageHandle,
                             uint64_t requestId = 0);
    void addGlobalFontAsset(std::string name,
                            FontHandle,
                            uint64_t requestId = 0);
    void addGlobalAudioAsset(std::string name,
                             AudioSourceHandle,
                             uint64_t requestId = 0);

    void removeGlobalImageAsset(std::string name, uint64_t requestId = 0);
    void removeGlobalFontAsset(std::string name, uint64_t requestId = 0);
    void removeGlobalAudioAsset(std::string name, uint64_t requestId = 0);

    ArtboardHandle instantiateArtboardNamed(
        FileHandle,
        std::string name,
        ArtboardListener* listener = nullptr,
        uint64_t requestId = 0);
    ArtboardHandle instantiateDefaultArtboard(
        FileHandle fileHandle,
        ArtboardListener* listener = nullptr,
        uint64_t requestId = 0)
    {
        return instantiateArtboardNamed(fileHandle, "", listener, requestId);
    }

    void setArtboardSize(ArtboardHandle,
                         float width,
                         float height,
                         float scale = 1,
                         uint64_t requestId = 0);

    void resetArtboardSize(ArtboardHandle, uint64_t requestId = 0);

    void deleteArtboard(ArtboardHandle, uint64_t requestId = 0);

    ViewModelInstanceHandle instantiateBlankViewModelInstance(
        FileHandle fileHandle,
        ArtboardHandle artboardHandle,
        ViewModelInstanceListener* listener = nullptr,
        uint64_t requestId = 0);

    ViewModelInstanceHandle instantiateBlankViewModelInstance(
        FileHandle fileHandle,
        std::string viewModelName,
        ViewModelInstanceListener* listener = nullptr,
        uint64_t requestId = 0);

    ViewModelInstanceHandle instantiateDefaultViewModelInstance(
        FileHandle fileHandle,
        ArtboardHandle artboardHandle,
        ViewModelInstanceListener* listener = nullptr,
        uint64_t requestId = 0)
    {
        return instantiateViewModelInstanceNamed(fileHandle,
                                                 artboardHandle,
                                                 "",
                                                 listener,
                                                 requestId);
    }

    ViewModelInstanceHandle instantiateDefaultViewModelInstance(
        FileHandle fileHandle,
        std::string viewModelName,
        ViewModelInstanceListener* listener = nullptr,
        uint64_t requestId = 0)
    {
        return instantiateViewModelInstanceNamed(fileHandle,
                                                 viewModelName,
                                                 "",
                                                 listener,
                                                 requestId);
    }

    ViewModelInstanceHandle instantiateViewModelInstanceNamed(
        FileHandle,
        ArtboardHandle,
        std::string viewModelInstanceName,
        ViewModelInstanceListener* listener = nullptr,
        uint64_t requestId = 0);

    ViewModelInstanceHandle instantiateViewModelInstanceNamed(
        FileHandle,
        std::string viewModelName,
        std::string viewModelInstanceName,
        ViewModelInstanceListener* listener = nullptr,
        uint64_t requestId = 0);

    ViewModelInstanceHandle referenceNestedViewModelInstance(
        ViewModelInstanceHandle,
        std::string path,
        ViewModelInstanceListener* listener = nullptr,
        uint64_t requestId = 0);

    ViewModelInstanceHandle referenceListViewModelInstance(
        ViewModelInstanceHandle,
        std::string path,
        int index,
        ViewModelInstanceListener* listener = nullptr,
        uint64_t requestId = 0);

    void fireViewModelTrigger(ViewModelInstanceHandle,
                              std::string path,
                              uint64_t requestId = 0);

    void setViewModelInstanceBool(ViewModelInstanceHandle,
                                  std::string path,
                                  bool value,
                                  uint64_t requestId = 0);
    void setViewModelInstanceNumber(ViewModelInstanceHandle,
                                    std::string path,
                                    float value,
                                    uint64_t requestId = 0);
    void setViewModelInstanceColor(ViewModelInstanceHandle,
                                   std::string path,
                                   ColorInt value,
                                   uint64_t requestId = 0);
    void setViewModelInstanceEnum(ViewModelInstanceHandle,
                                  std::string path,
                                  std::string value,
                                  uint64_t requestId = 0);
    void setViewModelInstanceString(ViewModelInstanceHandle,
                                    std::string path,
                                    std::string value,
                                    uint64_t requestId = 0);
    void setViewModelInstanceImage(ViewModelInstanceHandle,
                                   std::string path,
                                   RenderImageHandle value,
                                   uint64_t requestId = 0);
    void setViewModelInstanceBlob(ViewModelInstanceHandle,
                                  std::string path,
                                  BlobAssetHandle value,
                                  uint64_t requestId = 0);
    void setViewModelInstanceArtboard(ViewModelInstanceHandle,
                                      std::string path,
                                      ArtboardHandle value,
                                      uint64_t requestId = 0);
    void setViewModelInstanceNestedViewModel(ViewModelInstanceHandle,
                                             std::string path,
                                             ViewModelInstanceHandle value,
                                             uint64_t requestId = 0);
    void insertViewModelInstanceListViewModel(ViewModelInstanceHandle,
                                              std::string path,
                                              ViewModelInstanceHandle value,
                                              int index,
                                              uint64_t requestId = 0);

    void appendViewModelInstanceListViewModel(ViewModelInstanceHandle handle,
                                              std::string path,
                                              ViewModelInstanceHandle value,
                                              uint64_t requestId = 0)
    {
        insertViewModelInstanceListViewModel(handle,
                                             std::move(path),
                                             value,
                                             -1,
                                             requestId);
    }

    void removeViewModelInstanceListViewModel(
        ViewModelInstanceHandle,
        std::string path,
        int index,
        ViewModelInstanceHandle value = RIVE_NULL_HANDLE,
        uint64_t requestId = 0);

    void removeViewModelInstanceListViewModel(ViewModelInstanceHandle handle,
                                              std::string path,
                                              ViewModelInstanceHandle value,
                                              uint64_t requestId = 0)
    {
        removeViewModelInstanceListViewModel(handle,
                                             std::move(path),
                                             -1,
                                             value,
                                             requestId);
    }

    void swapViewModelInstanceListValues(ViewModelInstanceHandle handle,
                                         std::string path,
                                         int indexa,
                                         int indexb,
                                         uint64_t requestId = 0);

    void subscribeToViewModelProperty(ViewModelInstanceHandle handle,
                                      std::string path,
                                      DataType type,
                                      uint64_t requestId = 0);

    void unsubscribeToViewModelProperty(ViewModelInstanceHandle handle,
                                        std::string path,
                                        DataType type,
                                        uint64_t requestId = 0);

    void deleteViewModelInstance(ViewModelInstanceHandle,
                                 uint64_t requestId = 0);

    StateMachineHandle instantiateStateMachineNamed(
        ArtboardHandle,
        std::string name,
        StateMachineListener* listener = nullptr,
        uint64_t requestId = 0);
    StateMachineHandle instantiateDefaultStateMachine(
        ArtboardHandle artboardHandle,
        StateMachineListener* listener = nullptr,
        uint64_t requestId = 0)
    {
        return instantiateStateMachineNamed(artboardHandle,
                                            "",
                                            listener,
                                            requestId);
    }

    void bindViewModelInstance(StateMachineHandle,
                               ViewModelInstanceHandle,
                               uint64_t requestId = 0);

    // Sets the main (non-global) view model instance without rebinding. Call
    // bind() to apply.
    void setViewModelInstance(StateMachineHandle,
                              ViewModelInstanceHandle,
                              uint64_t requestId = 0);

    /**
     * Removes the main (non-global) view model instance from a state machine
     * without rebinding. Call bind() to create and apply its default main
     * instance.
     *
     * @param stateMachineHandle The state machine whose main instance should
     * be cleared.
     * @param requestId The identifier reported with any asynchronous error.
     */
    void clearViewModelInstance(StateMachineHandle stateMachineHandle,
                                uint64_t requestId = 0);

    // Sets/replaces the global view model instance bound under the given global
    // view model name without rebinding. Call bind() to apply. Reports a state
    // machine error if the name does not match a global view model.
    void setGlobalViewModelInstance(StateMachineHandle,
                                    std::string name,
                                    ViewModelInstanceHandle,
                                    uint64_t requestId = 0);

    /**
     * Removes the instance occupying a named global slot without rebinding,
     * preserving the main instance and every other global slot. Call bind() to
     * create and apply that slot's default instance. Reports a state machine
     * error if name does not identify a global view model.
     *
     * @param stateMachineHandle The state machine whose global slot should be
     * cleared.
     * @param name The global view model slot to clear.
     * @param requestId The identifier reported with any asynchronous error.
     */
    void clearGlobalViewModelInstance(StateMachineHandle stateMachineHandle,
                                      std::string name,
                                      uint64_t requestId = 0);

    // Returns a handle to the global view model instance currently bound under
    // the given name. Never creates: if none is bound, reports a view model
    // error and the returned handle maps to nothing.
    ViewModelInstanceHandle globalViewModelInstance(
        StateMachineHandle,
        std::string name,
        ViewModelInstanceListener* listener = nullptr,
        uint64_t requestId = 0);

    /**
     * Applies the state machine's current data context to its artboard and
     * state machine data binds in a single pass. Any missing main or global
     * view model instances are created from their defaults before binding.
     * Reports a state machine error asynchronously if the handle is invalid.
     *
     * @param stateMachineHandle The state machine whose data context should be
     * applied.
     * @param requestId The identifier reported with any asynchronous error.
     */
    void bind(StateMachineHandle stateMachineHandle, uint64_t requestId = 0);

    void advanceStateMachine(StateMachineHandle,
                             float timeToAdvance,
                             uint64_t requestId = 0);

    // Enable the semantic subsystem on the given state machine. Must be
    // called before diffs are delivered. Safe to call multiple times.
    void enableSemantics(StateMachineHandle, uint64_t requestId = 0);

    // Drain the current semantic diff for the given state machine.
    // The response is delivered via
    // StateMachineListener::onSemanticsDiffReceived when the diff is non-empty.
    // Output bounds are mapped to view space using the provided fit/alignment/
    // scale/view-bounds parameters.
    void drainSemanticsDiff(StateMachineHandle,
                            Fit fit,
                            Alignment alignment,
                            float scaleFactor,
                            Vec2D viewBounds,
                            uint64_t requestId = 0);

    // Pointer events
    struct PointerEvent
    {
        Fit fit = Fit::none; // the fit the artboard is drawn with
        Alignment alignment; // the alignment the artboard is drawn with
        Vec2D screenBounds;  // the bounds of coordinate system of the cursor
        Vec2D position;      // the cursor position
        float scaleFactor = 1.0f; // scale factor for things like retina display
        int pointerId = 0;        // stable pointer identifier for multitouch
    };

    // All pointer events will automatically convert between artboard and screen
    // space for you based on the values passed in the PointerEvent struct.

    void pointerMove(StateMachineHandle, PointerEvent, uint64_t requestId = 0);
    void pointerDown(StateMachineHandle, PointerEvent, uint64_t requestId = 0);
    void pointerUp(StateMachineHandle, PointerEvent, uint64_t requestId = 0);
    void pointerExit(StateMachineHandle, PointerEvent, uint64_t requestId = 0);

    void deleteStateMachine(StateMachineHandle, uint64_t requestId = 0);

    // Fire a semantic action (tap / increase / decrease) on the given node.
    // Fire-and-forget; reports a stateMachineError if the handle is unknown or
    // semantics isn't enabled. An unknown node id is a silent no-op.
    void fireSemanticAction(StateMachineHandle,
                            uint32_t semanticNodeId,
                            SemanticActionType actionType,
                            uint64_t requestId = 0);

    // Request focus on the given semantic node. Fire-and-forget; reports a
    // stateMachineError if the handle is unknown or semantics isn't enabled.
    // An unknown or non-focusable node id is a silent no-op.
    void requestSemanticFocus(StateMachineHandle,
                              uint32_t semanticNodeId,
                              uint64_t requestId = 0);

    // Clear all semantic focus. Called when the screen reader moves
    // focus entirely away from the hosting view.
    void clearSemanticFocus(StateMachineHandle, uint64_t requestId = 0);

    RenderImageHandle decodeImage(std::vector<uint8_t> imageEncodedBytes,
                                  RenderImageListener* listener = nullptr,
                                  uint64_t requestId = 0);
    // This is needed for unreal rhi because all images come pre-decoded and
    // uploaded to gpu.
    RenderImageHandle addExternalImage(rcp<RenderImage> externalImage,
                                       RenderImageListener* listener = nullptr,
                                       uint64_t requestId = 0);

    void deleteImage(RenderImageHandle, uint64_t requestId = 0);

    AudioSourceHandle decodeAudio(std::vector<uint8_t> imageEncodedBytes,
                                  AudioSourceListener* listener = nullptr,
                                  uint64_t requestId = 0);

    AudioSourceHandle addExternalAudio(rcp<AudioSource> externalAudio,
                                       AudioSourceListener* listener = nullptr,
                                       uint64_t requestId = 0);

    void deleteAudio(AudioSourceHandle, uint64_t requestId = 0);

    FontHandle decodeFont(std::vector<uint8_t> imageEncodedBytes,
                          FontListener* listener = nullptr,
                          uint64_t requestId = 0);

    FontHandle addExternalFont(rcp<Font> externalFont,
                               FontListener* listener = nullptr,
                               uint64_t requestId = 0);

    void deleteFont(FontHandle, uint64_t requestId = 0);

    BlobAssetHandle decodeBlob(std::vector<uint8_t> blobBytes,
                               BlobAssetListener* listener = nullptr,
                               uint64_t requestId = 0);

    BlobAssetHandle addExternalBlob(rcp<BlobAsset> externalBlob,
                                    BlobAssetListener* listener = nullptr,
                                    uint64_t requestId = 0);

    void deleteBlob(BlobAssetHandle, uint64_t requestId = 0);

    // Create unique draw key for draw.
    DrawKey createDrawKey();

    /**
     * Executes a one-time callback directly on the command server.
     *
     * This is an escape hatch for tests and runtime-specific operations that
     * cannot be represented by the shared command and message protocol. Do not
     * use it to implement capabilities common to multiple runtimes; add a
     * canonical command, message, and listener callback instead.
     *
     * @param callback The callback to execute on the command server.
     */
    void runOnce(CommandServerCallback);

    // Run draw function for given draw key, only the latest function passed
    // will be run per pollCommands.
    void draw(DrawKey, CommandServerDrawCallback);

    // Cancel a pending draw for the given key if it has already been admitted
    // to the current coalesced draw batch.
    void cancelDraw(DrawKey);

#ifdef TESTING
    // Sends a commandLoopBreak command to the server. This will cause the
    // processCommands to return even if there are more commands to consume.
    // This does not shutdown the server, it only causes processCommands to
    // return. To continue processing commands, another call to processCommands
    // is required.
    void testing_commandLoopBreak();
    FileListener* testing_getFileListener(FileHandle);
    ArtboardListener* testing_getArtboardListener(ArtboardHandle);
    StateMachineListener* testing_getStateMachineListener(StateMachineHandle);
#endif

    void disconnect();

    void requestViewModelNames(FileHandle, uint64_t requestId = 0);
    void requestGlobalViewModelNames(FileHandle, uint64_t requestId = 0);
    void requestArtboardNames(FileHandle, uint64_t requestId = 0);
    void requestFileAssets(FileHandle, uint64_t requestId = 0);
    void requestViewModelEnums(FileHandle, uint64_t requestId = 0);
    void requestViewModelPropertyDefinitions(FileHandle,
                                             std::string viewModelName,
                                             uint64_t requestId = 0);

    void requestViewModelInstanceNames(FileHandle,
                                       std::string viewModelName,
                                       uint64_t requestId = 0);

    void requestViewModelInstanceViewModelName(ViewModelInstanceHandle,
                                               uint64_t requestId = 0);

    void requestViewModelInstanceName(ViewModelInstanceHandle handle,
                                      uint64_t requestId = 0);

    void requestViewModelInstanceBool(ViewModelInstanceHandle,
                                      std::string path,
                                      uint64_t requestId = 0);

    void requestViewModelInstanceNumber(ViewModelInstanceHandle,
                                        std::string path,
                                        uint64_t requestId = 0);

    void requestViewModelInstanceColor(ViewModelInstanceHandle,
                                       std::string path,
                                       uint64_t requestId = 0);

    void requestViewModelInstanceEnum(ViewModelInstanceHandle,
                                      std::string path,
                                      uint64_t requestId = 0);

    void requestViewModelInstanceString(ViewModelInstanceHandle,
                                        std::string path,
                                        uint64_t requestId = 0);

    void requestViewModelInstanceListSize(ViewModelInstanceHandle,
                                          std::string path,
                                          uint64_t requestId = 0);

    void requestViewModelInstanceListClear(ViewModelInstanceHandle,
                                           std::string path,
                                           uint64_t requestId = 0);

    void setArtboardVolume(ArtboardHandle,
                           float volume,
                           uint64_t requestId = 0);
    void requestArtboardVolume(ArtboardHandle, uint64_t requestId = 0);

    void requestArtboardSize(ArtboardHandle, uint64_t requestId = 0);
    void requestStateMachineNames(ArtboardHandle, uint64_t requestId = 0);
    void requestDefaultViewModelInfo(ArtboardHandle,
                                     FileHandle,
                                     uint64_t requestId = 0);

    // Consume all messages received from the server.
    void processMessages();

    void setGlobalFileListener(FileListener* listener)
    {
        m_globalFileListener = listener;
    }
    void setGlobalArtboardListener(ArtboardListener* listener)
    {
        m_globalArtboardListener = listener;
    }
    void setGlobalStateMachineListener(StateMachineListener* listener)
    {
        m_globalStateMachineListener = listener;
    }
    void setGlobalViewModelInstanceListener(ViewModelInstanceListener* listener)
    {
        m_globalViewModelListener = listener;
    }
    void setGlobalRenderImageListener(RenderImageListener* listener)
    {
        m_globalImageListener = listener;
    }
    void setGlobalAudioSourceListener(AudioSourceListener* listener)
    {
        m_globalAudioListener = listener;
    }
    void setGlobalFontListener(FontListener* listener)
    {
        m_globalFontListener = listener;
    }
    void setGlobalBlobAssetListener(BlobAssetListener* listener)
    {
        m_globalBlobListener = listener;
    }

    bool focusNextSynchronized(StateMachineHandle);
    bool focusPreviousSynchronized(StateMachineHandle);
    void focusNext(StateMachineHandle, uint64_t requestId = 0);
    void focusPrevious(StateMachineHandle, uint64_t requestId = 0);
    void requestHasFocusNodes(StateMachineHandle, uint64_t requestId = 0);
    void clearFocus(StateMachineHandle, uint64_t requestId = 0);
    void requestFocusState(StateMachineHandle, uint64_t requestId = 0);

private:
    void registerListener(FileHandle handle, FileListener* listener)
    {
        assert(listener);
        assert(m_fileListeners.find(handle) == m_fileListeners.end());
        m_fileListeners.insert({handle, listener});
    }

    void registerListener(RenderImageHandle handle,
                          RenderImageListener* listener)
    {
        assert(listener);
        assert(m_imageListeners.find(handle) == m_imageListeners.end());
        m_imageListeners.insert({handle, listener});
    }

    void registerListener(AudioSourceHandle handle,
                          AudioSourceListener* listener)
    {
        assert(listener);
        assert(m_audioListeners.find(handle) == m_audioListeners.end());
        m_audioListeners.insert({handle, listener});
    }

    void registerListener(FontHandle handle, FontListener* listener)
    {
        assert(listener);
        assert(m_fontListeners.find(handle) == m_fontListeners.end());
        m_fontListeners.insert({handle, listener});
    }

    void registerListener(BlobAssetHandle handle, BlobAssetListener* listener)
    {
        assert(listener);
        assert(m_blobListeners.find(handle) == m_blobListeners.end());
        m_blobListeners.insert({handle, listener});
    }

    void registerListener(ArtboardHandle handle, ArtboardListener* listener)
    {
        assert(listener);
        assert(m_artboardListeners.find(handle) == m_artboardListeners.end());
        m_artboardListeners.insert({handle, listener});
    }

    void registerListener(ViewModelInstanceHandle handle,
                          ViewModelInstanceListener* listener)
    {
        assert(listener);
        assert(m_viewModelListeners.find(handle) == m_viewModelListeners.end());
        m_viewModelListeners.insert({handle, listener});
    }

    void registerListener(StateMachineHandle handle,
                          StateMachineListener* listener)
    {
        assert(listener);
        assert(m_stateMachineListeners.find(handle) ==
               m_stateMachineListeners.end());
        m_stateMachineListeners.insert({handle, listener});
    }

    // On 32-bit architectures, Handles are all uint64_t (not unique types), so
    // it will think we are re-declaring unregisterListener 3 times if we don't
    // add the listener pointer (even though it is not needed).

    void unregisterListener(FileHandle handle, FileListener* listener)
    {
        m_fileListeners.erase(handle);
    }

    void unregisterListener(RenderImageHandle handle,
                            RenderImageListener* listener)
    {
        m_imageListeners.erase(handle);
    }

    void unregisterListener(AudioSourceHandle handle,
                            AudioSourceListener* listener)
    {
        m_audioListeners.erase(handle);
    }

    void unregisterListener(FontHandle handle, FontListener* listener)
    {
        m_fontListeners.erase(handle);
    }

    void unregisterListener(BlobAssetHandle handle, BlobAssetListener* listener)
    {
        m_blobListeners.erase(handle);
    }

    void unregisterListener(ArtboardHandle handle, ArtboardListener* listener)
    {
        m_artboardListeners.erase(handle);
    }

    void unregisterListener(ViewModelInstanceHandle handle,
                            ViewModelInstanceListener* listener)
    {
        m_viewModelListeners.erase(handle);
    }

    void unregisterListener(StateMachineHandle handle,
                            StateMachineListener* listener)
    {
        m_stateMachineListeners.erase(handle);
    }

    enum class Command
    {
        loadFile,
        deleteFile,
        decodeImage,
        externalImage,
        decodeAudio,
        externalAudio,
        decodeFont,
        externalFont,
        decodeBlob,
        externalBlob,
        deleteImage,
        deleteAudio,
        deleteFont,
        deleteBlob,
        addImageFileAsset,
        addAudioFileAsset,
        addFontFileAsset,
        removeImageFileAsset,
        removeAudioFileAsset,
        removeFontFileAsset,
        instantiateArtboard,
        deleteArtboard,
        setArtboardSize,
        resetArtboardSize,
        instantiateViewModel,
        refNestedViewModel,
        refListViewModel,
        instantiateBlankViewModel,
        instantiateViewModelForArtboard,
        instantiateBlankViewModelForArtboard,
        setViewModelInstanceValue,
        addViewModelListValue,
        removeViewModelListValue,
        swapViewModelListValue,
        subscribeViewModelProperty,
        unsubscribeViewModelProperty,
        deleteViewModel,
        instantiateStateMachine,
        deleteStateMachine,
        advanceStateMachine,
        enableSemantics,
        drainSemanticsDiff,
        fireSemanticAction,
        requestSemanticFocus,
        clearSemanticFocus,
        bindViewModelInstance,
        setViewModelInstance,
        clearViewModelInstance,
        setGlobalViewModelInstance,
        clearGlobalViewModelInstance,
        getGlobalViewModelInstance,
        bind,
        runOnce,
        draw,
        cancelDraw,
        pointerMove,
        pointerDown,
        pointerUp,
        pointerExit,
        disconnect,
        // This will cause processCommands to return once received. We want to
        // ensure that we do not indefinetly block the calling thread. This is
        // how we achieve that.
        commandLoopBreak,
        // messages
        listViewModelEnums,
        listArtboards,
        listStateMachines,
        getDefaultViewModel,
        listViewModels,
        listGlobalViewModelNames,
        listViewModelInstanceNames,
        listViewModelProperties,
        listViewModelPropertyValue,
        getViewModelInstanceViewModelName,
        getViewModelInstanceName,
        getViewModelListSize,
        clearViewModelList,
        listFileAssets,
        setArtboardVolume,
        getArtboardVolume,
        getArtboardSize,
        focusNext,
        focusPrevious,
        requestHasFocusNodes,
        clearFocus,
        requestFocusState
    };

    enum class Message
    {
        // Same as commandLoopBreak for processMessages
        messageLoopBreak,
        viewModelEnumsListed,
        artboardsListed,
        stateMachinesListed,
        defaultViewModelReceived,
        viewModelInstanceViewModelNameReceived,
        viewModelInstanceNameReceived,
        viewModelsListend,
        globalViewModelNamesListed,
        viewModelInstanceNamesListed,
        viewModelPropertiesListed,
        viewModelPropertyValueReceived,
        viewModelListSizeReceived,
        viewModelListCleared,
        fileLoaded,
        fileDeleted,
        artboardInstantiated,
        stateMachineInstantiated,
        viewModelInstanceInstantiated,
        imageDecoded,
        imageDeleted,
        audioDecoded,
        audioDeleted,
        fontDecoded,
        fontDeleted,
        blobDecoded,
        blobDeleted,
        artboardDeleted,
        viewModelDeleted,
        stateMachineDeleted,
        stateMachineSettled,
        semanticsDiffReceived,
        fileAssetsListed,
        artboardSizeReceived,
        fileError,
        artboardError,
        viewModelError,
        imageError,
        audioError,
        fontError,
        blobError,
        stateMachineError,
        artboardVolumeReceived,
        hasFocusNodesReceived,
        focusStateReceived
    };

    friend class CommandServer;

    uint64_t m_currentFileHandleIdx = 0;
    uint64_t m_currentListHandleIdx = 0;
    uint64_t m_currentFontHandleIdx = 0;
    uint64_t m_currentArtboardHandleIdx = 0;
    uint64_t m_currentViewModelHandleIdx = 0;
    uint64_t m_currentRenderImageHandleIdx = 0;
    uint64_t m_currentBlobAssetHandleIdx = 0;
    uint64_t m_currentAudioSourceHandleIdx = 0;
    uint64_t m_currentStateMachineHandleIdx = 0;
    uint64_t m_currentDrawKeyIdx = 0;

    std::mutex m_commandMutex;
    std::condition_variable m_commandConditionVariable;
    PODStream m_commandStream;
    ObjectStream<rcp<RenderImage>> m_externalImages;
    ObjectStream<rcp<AudioSource>> m_externalAudioSources;
    ObjectStream<rcp<Font>> m_externalFonts;
    ObjectStream<rcp<BlobAsset>> m_externalBlobs;
    ObjectStream<std::vector<uint8_t>> m_byteVectors;
#ifdef WITH_RIVE_SCRIPTING
    ObjectStream<ScriptingContextFactory> m_scriptingContextFactories;
#endif
    ObjectStream<PointerEvent> m_pointerEvents;
    ObjectStream<std::string> m_names;
    ObjectStream<CommandServerCallback> m_callbacks;
    ObjectStream<CommandServerDrawCallback> m_drawCallbacks;

    // Messages streams
    std::mutex m_messageMutex;
    PODStream m_messageStream;
    ObjectStream<std::string> m_messageNames;
    ObjectStream<SemanticsDiff> m_messageSemanticsDiffs;

    // Listeners
    FileListener* m_globalFileListener = nullptr;
    RenderImageListener* m_globalImageListener = nullptr;
    AudioSourceListener* m_globalAudioListener = nullptr;
    FontListener* m_globalFontListener = nullptr;
    BlobAssetListener* m_globalBlobListener = nullptr;
    ArtboardListener* m_globalArtboardListener = nullptr;
    ViewModelInstanceListener* m_globalViewModelListener = nullptr;
    StateMachineListener* m_globalStateMachineListener = nullptr;

    std::unordered_map<FileHandle, FileListener*> m_fileListeners;
    std::unordered_map<RenderImageHandle, RenderImageListener*>
        m_imageListeners;
    std::unordered_map<AudioSourceHandle, AudioSourceListener*>
        m_audioListeners;
    std::unordered_map<FontHandle, FontListener*> m_fontListeners;
    std::unordered_map<BlobAssetHandle, BlobAssetListener*> m_blobListeners;
    std::unordered_map<ArtboardHandle, ArtboardListener*> m_artboardListeners;
    std::unordered_map<ViewModelInstanceHandle, ViewModelInstanceListener*>
        m_viewModelListeners;
    std::unordered_map<StateMachineHandle, StateMachineListener*>
        m_stateMachineListeners;
};

}; // namespace rive
