#ifdef WITH_RIVE_SCRIPTING
#ifdef WITH_RIVE_SCRIPTING_LUAU
// Only for the ScriptingVM to ScriptBackend conversion in backend().
#include "rive/lua/scripting_vm.hpp"
#endif
#include "rive/importers/text_asset_importer.hpp"
#endif
#include "rive/assets/script_asset.hpp"
#include "rive/signed_content_header.hpp"
#include "rive/component.hpp"
#include "rive/file.hpp"
#include "rive/importers/import_stack.hpp"
#include "rive/importers/scripted_object_importer.hpp"
#ifdef WITH_RIVE_SCRIPTING_WASM
#include "rive/wasm/wasm_scripting_vm.hpp"
#endif
#include "rive/script_input_artboard.hpp"
#include "rive/script_input_boolean.hpp"
#include "rive/script_input_color.hpp"
#include "rive/script_input_number.hpp"
#include "rive/script_input_string.hpp"
#include "rive/script_input_trigger.hpp"
#include "rive/script_input_viewmodel_property.hpp"
#include "rive/scripted/scripted_drawable.hpp"
#include "rive/scripted/scripted_layout.hpp"
#include "rive/scripted/scripted_object.hpp"
#include "rive/data_bind/data_bind.hpp"

using namespace rive;

ScriptInput::~ScriptInput()
{
  if (m_ownsDataBind && m_dataBind)
  {
    delete m_dataBind;
  }
}

ScriptInput* ScriptInput::from(Core* component)
{
  switch (component->coreType())
  {
    case ScriptInputArtboard::typeKey:
      return component->as<ScriptInputArtboard>();
    case ScriptInputBoolean::typeKey:
      return component->as<ScriptInputBoolean>();
    case ScriptInputColor::typeKey:
      return component->as<ScriptInputColor>();
    case ScriptInputNumber::typeKey:
      return component->as<ScriptInputNumber>();
    case ScriptInputString::typeKey:
      return component->as<ScriptInputString>();
    case ScriptInputTrigger::typeKey:
      return component->as<ScriptInputTrigger>();
    case ScriptInputViewModelProperty::typeKey:
      return component->as<ScriptInputViewModelProperty>();
  }
  return nullptr;
}

bool ScriptInput::takesArtboardSlot(const Component* input)
{
  return input->parentId() != 0u;
}

ScriptedObjectImporter* ScriptInput::ownerImporter(
    ImportStack& importStack,
    const Component* input)
{
  // The importer stays open until the next scripted object replaces it, so
  // after an owner this runtime can't read it still holds the one before.
  // Only hand it to inputs whose parent matches what that owner gives its
  // own inputs.
  auto importer = importStack.latest<ScriptedObjectImporter>(
      ScriptedDrawable::typeKey);
  if (importer == nullptr || input->parentId() != importer->inputParentId())
  {
    return nullptr;
  }
  return importer;
}

void ScriptInput::initScriptedValue() {}

bool ScriptInput::validateForColdScriptInit()
{
  return validateForScriptInit();
}

bool ScriptInput::hydrateScriptInput()
{
  initScriptedValue();
  return true;
}

bool ScriptInput::validateHydrationPrerequisites() { return true; }

#ifdef WITH_RIVE_SCRIPTING
ScriptBackend* ScriptAsset::backend()
{
  if (m_file == nullptr)
  {
    return nullptr;
  }
#ifdef WITH_RIVE_SCRIPTING_WASM
  if (m_wasmBackend != nullptr)
  {
    return m_wasmBackend;
  }
  if (m_file->wasmScriptingVM() != nullptr)
  {
    return m_file->wasmScriptingVM();
  }
#endif
#ifdef WITH_RIVE_SCRIPTING_LUAU
  return m_file->scriptingVM();
#else
  return nullptr;
#endif
}
#endif

bool ScriptAsset::initScriptedObject(ScriptedObject* object)
{
#ifdef WITH_RIVE_SCRIPTING
  if (backend() == nullptr)
  {
    return false;
  }
  return initScriptedObjectWith(object);
#else
  return false;
#endif
}

#if defined(WITH_RIVE_SCRIPTING)
void ScriptAsset::registrationComplete(int ref)
{
  if (isModule())
  {
    m_scriptRegistered = true;
  }
  else
  {
    generatorFunctionRef(ref);
    // Force re-verification on next init so that method detection (e.g.
    // draw) reflects the newly compiled script.
    m_initted = false;
  }
}
#endif

bool ScriptAsset::initScriptedObjectWith(ScriptedObject* object)
{
#if defined(WITH_RIVE_SCRIPTING)
  auto scriptBackend = backend();
  if (scriptBackend == nullptr)
  {
    return false;
  }

  int ref = scriptBackend->resolveGeneratorRef(generatorFunctionRef());
  if (ref == 0)
  {
    fprintf(
        stderr,
        "ScriptAsset doesn't have a generator function %s\n",
        name().c_str());
    return false;
  }

  if (!m_initted)
  {
    // The editor detected the implemented methods (by executing the
    // generator in its workspace) and serialized the bitfield; the runtime
    // never detects. Files predating this property decode to the all-bits
    // default (2097151), so they behave as "implements everything" and rely
    // on graceful dispatch (each callback no-ops when the method isn't
    // actually a function on the returned table).
    OptionalScriptedMethods::implementedMethods(
        serializedImplementedMethods() & methodMask);
#ifdef WITH_RIVE_TOOLS
    // Bit 15 was the removed drawCanvas callback: the editor detected it
    // on this script, so its canvas work never runs until moved into
    // draw. Legacy all-bits exports stay silent; the shipping runtime
    // stays quiet entirely, the editor console carries the migration.
    static const uint32_t kRetiredDrawCanvasBit = 1 << 15;
    static const uint32_t kAllMethodsDefault = (1 << 21) - 1;
    if (serializedImplementedMethods() != kAllMethodsDefault &&
        (serializedImplementedMethods() & kRetiredDrawCanvasBit) != 0)
    {
      fprintf(
          stderr,
          "rive: script implements drawCanvas, which is no longer "
          "called; move its body into draw\n");
    }
#endif
    m_needsPointerCheck = serializedImplementedMethods() ==
                          legacyImplementedMethods;
    m_initted = true;
  }
  object->implementedMethods(implementedMethods());
  if (!object->ensureScriptInitialized(scriptBackend, ref))
  {
    return false;
  }
  if (m_needsPointerCheck)
  {
    checkLegacyPointerHandlers(scriptBackend, object->self());
    // Recopy: the object took the bits before the check.
    object->implementedMethods(implementedMethods());
    m_needsPointerCheck = false;
  }
  return true;
#else
  return false;
#endif
}

#if defined(WITH_RIVE_SCRIPTING)
void ScriptAsset::checkLegacyPointerHandlers(ScriptBackend* vm, int self)
{
  static const struct
  {
    const char* name;
    int bit;
  } handlers[] = {
      {"pointerDown", m_wantsPointerDownBit},
      {"pointerMove", m_wantsPointerMoveBit},
      {"pointerUp", m_wantsPointerUpBit},
      {"pointerExit", m_wantsPointerExitBit},
  };
  int bits = implementedMethods();
  for (const auto& handler : handlers)
  {
    if (!vm->hasMethod(self, handler.name))
    {
      bits &= ~handler.bit;
    }
  }
  implementedMethods(bits);
}
#endif

bool ScriptAsset::decode(SimpleArray<uint8_t>& data, Factory* factory)
{
#ifdef WITH_RIVE_SCRIPTING
  m_verified = false;

  // For in-band bytecode, isSigned should always be false (signature is
  // stored separately for aggregate verification).
  SignedContentHeader header(Span<const uint8_t>(data.data(), data.size()));
  if (!header.isValid())
  {
    return false;
  }

  // Store just the bytecode (without header) for later verification and use.
  auto bytecode = header.content();
  m_bytecode = SimpleArray<uint8_t>(bytecode.data(), bytecode.size());
#endif
  return true;
}

bool ScriptAsset::bytecode(Span<uint8_t> data)
{
#ifdef WITH_RIVE_SCRIPTING
  SignedContentHeader header(Span<const uint8_t>(data.data(), data.size()));
  if (!header.isValid())
  {
    m_verified = false;
    return false;
  }

  auto bytecode = header.content();

  if (!header.isSigned())
  {
    // Unsigned bytecode - mark as unverified
    m_verified = false;
    m_bytecode = SimpleArray<uint8_t>(bytecode.data(), bytecode.size());
    return true;
  }

  if (!verifiesContentSignature(header.signature(), bytecode))
  {
    // Forged.
    m_verified = false;
    return false;
  }
  m_verified = true;
  m_bytecode = SimpleArray<uint8_t>(bytecode.data(), bytecode.size());
#endif
  return true;
}