/*
 * 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
