/*
 * Copyright 2025 Rive
 */

#pragma once

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

namespace rive
{

// Server-side worker that executes commands from a CommandQueue.
class CommandServer
{
public:
    CommandServer(rcp<CommandQueue>, Factory*);
    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&);

    File* getFile(FileHandle) const;
    bool getWasDisconnected() const { return m_wasDisconnectReceived; }
    RenderImage* getImage(RenderImageHandle) const;
    AudioSource* getAudioSource(AudioSourceHandle) const;
    Font* getFont(FontHandle) 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 imidiatly after checking messages. If there are none just returns
    // returns !m_wasDisconnectReceived.
    bool processCommands();
    // Blocks and runs waitMessages until disconnect is received.
    void serveUntilDisconnect();

    struct Subscription
    {
        // The request Id for sbuscribing to this particular property.
        uint64_t requestId;
        // Information about the property we want to "subsribe" to.
        PropertyData data;
        // The root view model of 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_getSubsciptions() 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

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 in seperate header to avoid including StateMachineInstance in
        // the main CommandServer header
        ~SynchronizedStateMachine();
        SynchronizedStateMachine& operator=(SynchronizedStateMachine&& other)
        {
            instance = std::move(other.instance);
            return *this;
        }
        SynchronizedStateMachine() = default;
        SynchronizedStateMachine(
            std::unique_ptr<StateMachineInstance> instance) :
            instance(std::move(instance))
        {}
        std::unique_ptr<StateMachineInstance> instance;
        // This mutex is used to ensure that a specific state machine instance
        // is not being advanced at the same time a sync mouse event is being
        // processed.
        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 statemachine 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 statemachine assosiated 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<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<CommandFileAssetLoader> m_fileAssetLoader;
};
}; // namespace rive
