/*
 * Copyright 2025 Rive
 */

#pragma once

#include "rive/command_queue.hpp"
#include "rive/hit_result.hpp"
#include "rive/math/mat2d.hpp"
#include <iostream>
#include <sstream>
#include <thread>
#include <unordered_map>
#include <type_traits>

namespace rive
{
class ScriptingContext;
class GlobalAssetRegistry;

// Server-side worker that executes commands from a CommandQueue.
class CommandServer
{
public:
    /**
     * Creates the server that executes commands from commandQueue.
     *
     * @param commandQueue The queue from which commands are read.
     * @param factory The factory used to create runtime resources.
     * @param internalFileAssetLoader An optional FileAssetLoader for loading
     * out-of-band asset contents without using command-queue global assets.
     * Provide a loader that recognizes and loads the assets it owns, returning
     * true from FileAssetLoader::loadContents for those assets. This is
     * typically used by an embedder that already has its own asset-loading
     * path. Leave it null when out-of-band images, audio, and fonts should be
     * handled through the command queue.
     */
    CommandServer(rcp<CommandQueue> commandQueue,
                  Factory* factory,
                  rcp<rive::FileAssetLoader> internalFileAssetLoader = nullptr);
    virtual ~CommandServer();

    Factory* factory() const { return m_factory; }

    rive::HitResult pointerDownSynchronized(StateMachineHandle,
                                            const CommandQueue::PointerEvent&);
    rive::HitResult pointerMoveSynchronized(StateMachineHandle,
                                            const CommandQueue::PointerEvent&);
    rive::HitResult pointerUpSynchronized(StateMachineHandle,
                                          const CommandQueue::PointerEvent&);
    // Whether a listener under the event's position responds to presses of
    // its button. Lets a host keep a mouse button for its own use wherever
    // nothing in the scene wants it.
    bool listensToButtonAtSynchronized(StateMachineHandle,
                                       const CommandQueue::PointerEvent&);

    File* getFile(FileHandle) const;
    bool getWasDisconnected() const { return m_wasDisconnectReceived; }
    RenderImage* getImage(RenderImageHandle) const;
    AudioSource* getAudioSource(AudioSourceHandle) const;
    Font* getFont(FontHandle) const;
    BlobAsset* getBlob(BlobAssetHandle) const;
    ArtboardInstance* getArtboardInstance(ArtboardHandle) const;
    rcp<BindableArtboard> getBindableArtboard(ArtboardHandle) const;
    StateMachineInstance* getStateMachineInstance(StateMachineHandle) const;
    ViewModelInstanceRuntime* getViewModelInstance(
        ViewModelInstanceHandle) const;
    ViewModelInstanceHandle getHandleForInstance(
        ViewModelInstanceRuntime*) const;
    // Wait for queue to not be empty, then returns pollMessages.
    bool waitCommands();
    // Returns immediately after checking messages. If there are none just
    // returns !m_wasDisconnectReceived.
    bool processCommands();
    // Blocks and runs waitMessages until disconnect is received.
    void serveUntilDisconnect();

    /**
     * Posts a runtime-defined message to the command queue.
     *
     * This is intended for host runtime integrations that need to report
     * information discovered while executing command server work, such as from
     * runOnce or draw callbacks. The command queue forwards the message through
     * its RuntimeMessageListener when processMessages() runs. Rive does not
     * interpret the tag or payload.
     *
     * @param tag Runtime-owned message type identifier.
     * @param payload Runtime-owned serialized message bytes.
     */
    void postRuntimeMessage(uint32_t tag, std::vector<uint8_t> payload);

    struct Subscription
    {
        // The request Id for subscribing to this particular property.
        uint64_t requestId;
        // Information about the property we want to "subscribe" to.
        PropertyData data;
        // The root view model from the perspective of the path in data.name.
        ViewModelInstanceHandle rootViewModel;
    };

#ifdef TESTING
    // Expose cursorPosForPointerEvent for testing.
    Vec2D testing_cursorPosForPointerEvent(StateMachineInstance* instance,
                                           CommandQueue::PointerEvent event)
    {
        return cursorPosForPointerEvent(instance, event);
    }

    const std::vector<Subscription>& testing_getSubscriptions() const
    {
        return m_propertySubscriptions;
    }

    RenderImageHandle testing_globalImageNamed(std::string name);
    AudioSourceHandle testing_globalAudioNamed(std::string name);
    FontHandle testing_globalFontNamed(std::string name);

    bool testing_globalImageContains(std::string name);
    bool testing_globalAudioContains(std::string name);
    bool testing_globalFontContains(std::string name);

#ifndef NDEBUG
    // Used because "sync pointer events" test needs to be able to
    // make the server on one thread but access it from another
    void testing_overrideThreadID(std::thread::id threadID)
    {
        m_threadID = threadID;
    }
#endif
#endif

    bool focusNextSynchronized(StateMachineHandle);
    bool focusPreviousSynchronized(StateMachineHandle);

    /** @copydoc CommandQueue::focusNextWithResultSynchronized */
    CommandQueue::FocusTraversalResult focusNextWithResultSynchronized(
        StateMachineHandle stateMachineHandle);

    /** @copydoc CommandQueue::focusPreviousWithResultSynchronized */
    CommandQueue::FocusTraversalResult focusPreviousWithResultSynchronized(
        StateMachineHandle stateMachineHandle);

    /** @copydoc CommandQueue::keyInputSynchronized */
    bool keyInputSynchronized(StateMachineHandle stateMachineHandle,
                              Key key,
                              KeyModifiers modifiers,
                              bool isPressed,
                              bool isRepeat);

    /** @copydoc CommandQueue::focusInDirectionSynchronized */
    bool focusInDirectionSynchronized(StateMachineHandle stateMachineHandle,
                                      Direction direction);

private:
    friend class CommandQueue;

    template <typename HandleType> class ErrorReporter
    {
    public:
        ErrorReporter(CommandServer* server,
                      HandleType handle,
                      uint64_t requestId,
                      CommandQueue::Message message) :
            m_server(server), m_lock(m_server->m_commandQueue->m_messageMutex)
        {
            assert(server);
            assert(message >= CommandQueue::Message::fileError &&
                   message <= CommandQueue::Message::stateMachineError);

            std::cerr << "ERROR : ";
            m_server->m_commandQueue->m_messageStream << message;
            m_server->m_commandQueue->m_messageStream << handle;
            m_server->m_commandQueue->m_messageStream << requestId;
        }

        ErrorReporter& operator<<(std::vector<std::string> vector)
        {
            m_ostringstream << "{ ";
            for (auto& s : vector)
                m_ostringstream << s << ",";
            m_ostringstream << "} ";
            return *this;
        }

        template <typename T> ErrorReporter& operator<<(const T& t)
        {
            m_ostringstream << t;
            return *this;
        }

        ~ErrorReporter()
        {
            std::string str = m_ostringstream.str();
            assert(!str.empty());
            std::cerr << str << "\n";
            m_server->m_commandQueue->m_messageNames << std::move(str);
        }

        CommandServer* m_server;
        std::unique_lock<std::mutex> m_lock;
        std::ostringstream m_ostringstream;
    };

    void checkPropertySubscriptions();

    Vec2D cursorPosForPointerEvent(StateMachineInstance*,
                                   const CommandQueue::PointerEvent&);

    void cleanupArtboard(ArtboardHandle handle, uint64_t requestId)
    {
        auto itr = m_artboards.find(handle);
        if (itr != m_artboards.end())
        {
            auto dependencyItr = m_artboardDependencies.find(handle);
            if (dependencyItr != m_artboardDependencies.end())
            {
                auto& stateMachineVector = dependencyItr->second;
                for (auto stateMachine : stateMachineVector)
                {
                    if (m_stateMachines.erase(stateMachine) > 0)
                    {
                        std::unique_lock<std::mutex> lock(
                            m_commandQueue->m_messageMutex);
                        m_commandQueue->m_messageStream
                            << CommandQueue::Message::stateMachineDeleted;
                        m_commandQueue->m_messageStream << stateMachine;
                        m_commandQueue->m_messageStream << requestId;
                    }
                }

                m_artboardDependencies.erase(dependencyItr);
            }
            m_artboards.erase(itr);
            std::unique_lock<std::mutex> lock(m_commandQueue->m_messageMutex);
            m_commandQueue->m_messageStream
                << CommandQueue::Message::artboardDeleted;
            m_commandQueue->m_messageStream << handle;
            m_commandQueue->m_messageStream << requestId;
        }
    }

    struct SynchronizedStateMachine : RefCnt<SynchronizedStateMachine>
    {
        // Kept out of line to avoid including StateMachineInstance in the main
        // CommandServer header.
        ~SynchronizedStateMachine();
        SynchronizedStateMachine& operator=(SynchronizedStateMachine&& other);
        SynchronizedStateMachine() = default;
        SynchronizedStateMachine(
            std::unique_ptr<StateMachineInstance> instance);
        std::unique_ptr<StateMachineInstance> instance;
        Mat2D m_lastSemanticsTransform;
        bool m_hasLastSemanticsTransform = false;
        // This mutex ensures that a specific state machine instance is not
        // advanced while a synchronized input or focus operation is running.
        std::mutex m_mutex;
    };

    rcp<CommandServer::SynchronizedStateMachine> getStateMachineWrapper(
        StateMachineHandle handle);

    bool m_wasDisconnectReceived = false;
    const rcp<CommandQueue> m_commandQueue;
    Factory* const m_factory;
#ifndef NDEBUG
#ifdef TESTING
    std::thread::id m_threadID;
#else
    const std::thread::id m_threadID;
#endif
#endif

    // Vector to iterate on for subscriptions. This is a vector instead of a map
    // because we iterate through the entire vector every frame anyway.
    std::vector<Subscription> m_propertySubscriptions;

    // Dependencies
    // When a file gets deleted artboards and state machines become invalid.
    // Here we hold a reference to the artboard only because that artboard has a
    // dependency to the State Machine.
    std::unordered_map<FileHandle, std::vector<ArtboardHandle>>
        m_fileDependencies;
    // When an artboard gets deleted the state machine associated with it is
    // also now invalid.
    std::unordered_map<ArtboardHandle, std::vector<StateMachineHandle>>
        m_artboardDependencies;

    // Handle Maps
    std::unordered_map<FileHandle, rcp<File>> m_files;
    std::unordered_map<FontHandle, rcp<Font>> m_fonts;
    std::unordered_map<RenderImageHandle, rcp<RenderImage>> m_images;
    std::unordered_map<BlobAssetHandle, rcp<BlobAsset>> m_blobs;
    std::unordered_map<AudioSourceHandle, rcp<AudioSource>> m_audioSources;
    std::unordered_map<ArtboardHandle, rcp<BindableArtboard>> m_artboards;
    std::unordered_map<ViewModelInstanceHandle, rcp<ViewModelInstanceRuntime>>
        m_viewModels;
    std::unordered_map<StateMachineHandle, rcp<SynchronizedStateMachine>>
        m_stateMachines;
    std::mutex m_stateMachineAccessMutex;

    std::unordered_map<DrawKey, CommandServerDrawCallback> m_uniqueDraws;

    class CommandFileAssetLoader;
    rcp<GlobalAssetRegistry> m_globalAssetRegistry;
    rcp<FileAssetLoader> m_internalFileAssetLoader;
};
}; // namespace rive
