#include "rive/file.hpp"
#include "rive/bindable_artboard.hpp"
#include "rive/runtime_header.hpp"
#include "rive/animation/animation.hpp"
#include "rive/artboard_component_list.hpp"
#include "rive/core/field_types/core_color_type.hpp"
#include "rive/core/field_types/core_double_type.hpp"
#include "rive/core/field_types/core_string_type.hpp"
#include "rive/core/field_types/core_uint_type.hpp"
#include "rive/generated/animation/listener_types/listener_input_type_semantic_base.hpp"
#include "rive/generated/core_registry.hpp"
#include "rive/animation/listener_types/listener_input_type_semantic.hpp"
#include "rive/importers/artboard_importer.hpp"
#include "rive/importers/backboard_importer.hpp"
#include "rive/importers/bindable_property_importer.hpp"
#include "rive/importers/data_converter_group_importer.hpp"
#include "rive/importers/data_converter_formula_importer.hpp"
#include "rive/importers/enum_importer.hpp"
#include "rive/importers/file_asset_importer.hpp"
#include "rive/importers/text_asset_importer.hpp"
#include "rive/importers/import_stack.hpp"
#ifdef WITH_RIVE_SCRIPTING
#ifdef WITH_RIVE_SCRIPTING_LUAU
#include "rive/lua/rive_lua_libs.hpp"
#include "rive/lua/lua_state.hpp"
#endif
#endif
#include "rive/importers/keyed_object_importer.hpp"
#include "rive/importers/keyed_property_importer.hpp"
#include "rive/importers/linear_animation_importer.hpp"
#include "rive/importers/scripted_object_importer.hpp"
#include "rive/importers/state_machine_importer.hpp"
#include "rive/importers/state_machine_listener_importer.hpp"
#include "rive/importers/state_machine_layer_importer.hpp"
#include "rive/importers/layer_state_importer.hpp"
#include "rive/importers/state_transition_importer.hpp"
#include "rive/importers/state_machine_layer_component_importer.hpp"
#include "rive/importers/transition_viewmodel_condition_importer.hpp"
#include "rive/importers/listener_input_type_gamepad_importer.hpp"
#include "rive/importers/listener_input_type_keyboard_importer.hpp"
#include "rive/importers/listener_input_type_semantic_importer.hpp"
#include "rive/importers/viewmodel_importer.hpp"
#include "rive/importers/viewmodel_instance_importer.hpp"
#include "rive/importers/viewmodel_instance_list_importer.hpp"
#include "rive/importers/data_bind_path_importer.hpp"
#include "rive/animation/blend_state_transition.hpp"
#include "rive/animation/any_state.hpp"
#include "rive/animation/entry_state.hpp"
#include "rive/animation/exit_state.hpp"
#include "rive/animation/animation_state.hpp"
#include "rive/animation/blend_state_1d_input.hpp"
#include "rive/animation/blend_state_1d_viewmodel.hpp"
#include "rive/animation/blend_state_direct.hpp"
#include "rive/animation/transition_property_viewmodel_comparator.hpp"
#include "rive/constraints/scrolling/scroll_physics.hpp"
#include "rive/data_bind/data_bind.hpp"
#include "rive/data_bind/data_bind_path.hpp"
#include "rive/data_bind/bindable_property.hpp"
#include "rive/data_bind/bindable_property_artboard.hpp"
#include "rive/data_bind/bindable_property_asset.hpp"
#include "rive/data_bind/bindable_property_viewmodel.hpp"
#include "rive/data_bind/bindable_property_number.hpp"
#include "rive/data_bind/bindable_property_string.hpp"
#include "rive/data_bind/bindable_property_color.hpp"
#include "rive/data_bind/bindable_property_enum.hpp"
#include "rive/data_bind/bindable_property_integer.hpp"
#include "rive/data_bind/bindable_property_boolean.hpp"
#include "rive/data_bind/bindable_property_trigger.hpp"
#include "rive/data_bind/bindable_property_asset.hpp"
#include "rive/data_bind/converters/data_converter_group.hpp"
#include "rive/data_bind/converters/data_converter_number_to_list.hpp"
#include "rive/assets/file_asset.hpp"
#include "rive/assets/audio_asset.hpp"
#include "rive/assets/blob_asset.hpp"
#include "rive/assets/script_asset.hpp"
#include "rive/assets/script_module_asset.hpp"
#ifdef WITH_RIVE_SCRIPTING_WASM
#include "rive/wasm/wasm_scripting_vm.hpp"
#endif
#include "rive/assets/shader_asset.hpp"
#include "rive/assets/file_asset_contents.hpp"
#include "rive/scripted/scripted_drawable.hpp"
#include "rive/scripted/scripted_layout.hpp"
#include "rive/scripted/scripted_object.hpp"
#include "rive/scripted/scripted_path_effect.hpp"
#include "rive/scripted/scripted_interpolator.hpp"
#include "rive/viewmodel/viewmodel.hpp"
#include "rive/viewmodel/data_enum.hpp"
#include "rive/viewmodel/viewmodel_instance.hpp"
#include "rive/viewmodel/viewmodel_instance_list.hpp"
#include "rive/viewmodel/viewmodel_instance_viewmodel.hpp"
#include "rive/viewmodel/viewmodel_instance_number.hpp"
#include "rive/viewmodel/viewmodel_instance_string.hpp"
#include "rive/viewmodel/viewmodel_property_viewmodel.hpp"
#include "rive/viewmodel/viewmodel_property_string.hpp"
#include "rive/viewmodel/viewmodel_property_number.hpp"
#include "rive/viewmodel/viewmodel_property_enum.hpp"
#include "rive/viewmodel/viewmodel_property_enum_custom.hpp"
#include "rive/viewmodel/viewmodel_property_enum_system.hpp"
#include "rive/viewmodel/viewmodel_property_list.hpp"
#include "rive/viewmodel/viewmodel_property_trigger.hpp"
#include "rive/viewmodel/viewmodel_property_symbol_list_index.hpp"
#include "rive/viewmodel/runtime/viewmodel_runtime.hpp"
#include "rive/view_model_type.hpp"

// Default namespace for Rive Cpp code
using namespace rive;

#if defined(DEBUG)
size_t File::debugTotalFileCount = 0;
#endif

#if !defined(RIVE_FMT_U64)
#if defined(__ANDROID__)
#if INTPTR_MAX == INT64_MAX
#define RIVE_FMT_U64 "%lu"
#define RIVE_FMT_I64 "%ld"
#else
#define RIVE_FMT_U64 "%llu"
#define RIVE_FMT_I64 "%lld"
#endif
#elif defined(_WIN32)
#define RIVE_FMT_U64 "%lld"
#define RIVE_FMT_I64 "%llu"
#else
#include <inttypes.h>
#define RIVE_FMT_U64 "%" PRIu64
#define RIVE_FMT_I64 "%" PRId64
#endif
#endif

// Import a single Rive runtime object.
// Used by the file importer.
#ifdef WITH_RIVE_SCRIPTING_WASM
void File::adoptWasmScriptingVM(std::unique_ptr<WasmScriptingVM> vm)
{
    m_wasmVMs.clear();
    WasmScriptingVM* raw = vm.get();
    m_wasmVMs.push_back(std::move(vm));
    for (auto& asset : m_fileAssets)
    {
        if (asset->is<ScriptAsset>())
        {
            asset->as<ScriptAsset>()->wasmBackend(raw);
        }
    }
}

bool File::applyWasmRegistration(const std::string& moduleName, int ref)
{
    for (auto& asset : m_fileAssets)
    {
        if (!asset->is<ScriptAsset>())
        {
            continue;
        }
        auto* script = asset->as<ScriptAsset>();
        if (script->moduleName() == moduleName)
        {
            if (!script->isModule() && ref != 0)
            {
                script->registrationComplete(ref);
            }
            return true;
        }
    }
    return false;
}
#endif

static Core* readRuntimeObject(BinaryReader& reader,
                               const RuntimeHeader& header)
{
    auto coreObjectKey = reader.readVarUintAs<int>();
    auto object = CoreRegistry::makeCoreInstance(coreObjectKey);
    while (true)
    {
        auto propertyKey = reader.readVarUintAs<uint16_t>();
        if (propertyKey == 0)
        {
            // Terminator. https://media.giphy.com/media/7TtvTUMm9mp20/giphy.gif
            break;
        }

        if (reader.hasError())
        {
            delete object;
            return nullptr;
        }
        if (object == nullptr || !object->deserialize(propertyKey, reader))
        {
            // We have an unknown object or property, first see if core knows
            // the property type.
            int id = CoreRegistry::propertyFieldId(propertyKey);
            if (id == -1)
            {
                // No, check if it's in toc.
                id = header.propertyFieldId(propertyKey);
            }

            if (id == -1)
            {
                // Still couldn't find it, give up.
                fprintf(stderr,
                        "Unknown property key %d, missing from property ToC.\n",
                        propertyKey);
                delete object;
                return nullptr;
            }

            switch (id)
            {
                case CoreUintType::id:
                    // Uint64 shares the uint type id; skip the full range so
                    // an unknown 64 bit value never aborts the read.
                    reader.readVarUint64();
                    break;
                case CoreStringType::id:
                    CoreStringType::deserialize(reader);
                    break;
                case CoreDoubleType::id:
                    CoreDoubleType::deserialize(reader);
                    break;
                case CoreColorType::id:
                    CoreColorType::deserialize(reader);
                    break;
            }
        }
    }
    if (object == nullptr)
    {
        // fprintf(stderr,
        //         "File contains an unknown object with coreType " RIVE_FMT_U64
        //         ", which " "this runtime doesn't understand.\n",
        //         coreObjectKey);
        return nullptr;
    }
#ifdef WITH_RIVE_EDITOR
    // The .riv importer is exclusively the runtime path (editor flow
    // hydrates via coop, never through here), so imported objects are
    // fully wired by the import stack — mark them validated or the
    // editor build's hasValidated() gate starves every generated
    // ${name}Changed() on runtime instances (frozen animation dirt,
    // silent VMI value callbacks).
    object->markValidated();
#endif
    return object;
}

bool File::deterministicMode = false;

File::File(Factory* factory, rcp<FileAssetLoader> assetLoader) :
    m_factory(factory), m_assetLoader(std::move(assetLoader))
{
#if defined(DEBUG)
    debugTotalFileCount++;
#endif
    assert(factory);
}

File::~File()
{
#if defined(DEBUG)
    debugTotalFileCount--;
#endif
#ifdef WITH_RIVE_SCRIPTING_LUAU
    cleanupScriptingVM();
#endif
    for (auto artboard : m_artboards)
    {
        delete artboard;
    }
    for (auto& viewModel : m_ViewModels)
    {
        viewModel->unref();
    }
#ifdef WITH_RIVE_TOOLS
    m_viewModelInstanceRegistrar = nullptr;
#endif
    for (auto& enumData : m_Enums)
    {
        enumData->unref();
    }
    for (auto& dataConverter : m_DataConverters)
    {
        delete dataConverter;
    }
    for (auto& keyframeInterpolator : m_keyframeInterpolators)
    {
        delete keyframeInterpolator;
    }
    for (auto& physics : m_scrollPhysics)
    {
        delete physics;
    }
    delete m_backboard;
}

rcp<File> File::import(Span<const uint8_t> bytes,
                       Factory* factory,
                       ImportResult* result,
                       rcp<FileAssetLoader> assetLoader,
                       ScriptingVM* vm)
{
    BinaryReader reader(bytes);
    RuntimeHeader header;
    if (!RuntimeHeader::read(reader, header))
    {
        fprintf(stderr, "Bad header\n");
        if (result)
        {
            *result = ImportResult::malformed;
        }
        return nullptr;
    }
    if (header.majorVersion() != majorVersion)
    {
        fprintf(stderr,
                "Unsupported version %u.%u expected %u.%u.\n",
                header.majorVersion(),
                header.minorVersion(),
                majorVersion,
                minorVersion);
        if (result)
        {
            *result = ImportResult::unsupportedVersion;
        }
        return nullptr;
    }
    auto file = make_rcp<File>(factory, std::move(assetLoader));
#ifdef WITH_RIVE_SCRIPTING_LUAU
    if (vm != nullptr)
    {
        file->setScriptingVM(ref_rcp(vm));
    }
#else
    (void)vm;
#endif

    auto readResult = file->read(reader, header);
    if (result)
    {
        *result = readResult;
    }
    if (readResult != ImportResult::success)
    {
        file.reset(nullptr);
    }
    return file;
}

ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header)
{
    ImportStack importStack;
    importStack.version(header.majorVersion(), header.minorVersion());
#ifdef WITH_RIVE_SCRIPTING
    std::vector<InBandContent> inBandContent;
#endif
    // TODO: @hernan consider moving this to a special importer. It's not that
    // simple because Core doesn't have a typeKey, so it should be treated as
    // a special case. In any case, it's not that bad having it here for now.
    Core* lastBindableObject = nullptr;
    while (!reader.reachedEnd())
    {
        auto object = readRuntimeObject(reader, header);
        if (object == nullptr)
        {
            importStack.readNullObject();
            continue;
        }
        if (!object->is<DataBind>())
        {
            lastBindableObject = object;
        }
        else if (lastBindableObject != nullptr)
        {
            object->as<DataBind>()->target(lastBindableObject);
        }
        if (object->import(importStack) == StatusCode::Ok)
        {
            switch (object->coreType())
            {
                case Backboard::typeKey:
                    m_backboard = object->as<Backboard>();
                    break;
                case Artboard::typeKey:
                {
                    Artboard* ab = object->as<Artboard>();
                    ab->m_Factory = m_factory;
                    m_artboards.push_back(ab);
                }
                break;
                case ImageAsset::typeKey:
                case FontAsset::typeKey:
                case AudioAsset::typeKey:
                case BlobAsset::typeKey:
                case ScriptAsset::typeKey:
                case ScriptModuleAsset::typeKey:
                case ShaderAsset::typeKey:
                {
                    auto fa = object->as<FileAsset>();
                    m_fileAssets.push_back(rcp<FileAsset>(fa));
                    if (object->coreType() == AudioAsset::typeKey)
                    {
                        m_hasAudio = true;
                    }
                }
                break;
                case ViewModel::typeKey:
                {
                    auto vmc = object->as<ViewModel>();
                    m_ViewModels.push_back(vmc);
                    break;
                }
                case DataEnum::typeKey:
                case DataEnumCustom::typeKey:
                {
                    auto de = object->as<DataEnum>();
                    m_Enums.push_back(de);
                    break;
                }
                case ViewModelPropertyEnumCustom::typeKey:
                {
                    auto vme = object->as<ViewModelPropertyEnumCustom>();
                    if (vme->enumId() < m_Enums.size())
                    {
                        vme->dataEnum(m_Enums[vme->enumId()]);
                    }
                }
                break;
            }
        }
        else
        {
            if (lastBindableObject == object)
            {
                lastBindableObject = nullptr;
            }
            fprintf(stderr,
                    "Failed to import object of type %d\n",
                    object->coreType());
            delete object;
            continue;
        }
        std::unique_ptr<ImportStackObject> stackObject = nullptr;
        auto stackType = object->coreType();

        switch (stackType)
        {
            case Backboard::typeKey:
                stackObject = std::make_unique<BackboardImporter>(
                    object->as<Backboard>());
                static_cast<BackboardImporter*>(stackObject.get())->file(this);
                break;
            case Artboard::typeKey:
                stackObject =
                    std::make_unique<ArtboardImporter>(object->as<Artboard>());
                break;
            case DataEnumCustom::typeKey:
                stackObject = std::make_unique<EnumImporter>(
                    object->as<DataEnumCustom>());
                break;
            case LinearAnimation::typeKey:
                stackObject = std::make_unique<LinearAnimationImporter>(
                    object->as<LinearAnimation>());
                break;
            case KeyedObject::typeKey:
                stackObject = std::make_unique<KeyedObjectImporter>(
                    object->as<KeyedObject>());
                break;
            case KeyedProperty::typeKey:
            {
                auto importer = importStack.latest<LinearAnimationImporter>(
                    LinearAnimation::typeKey);
                if (importer == nullptr)
                {
                    return ImportResult::malformed;
                }
                stackObject = std::make_unique<KeyedPropertyImporter>(
                    importer->animation(),
                    object->as<KeyedProperty>());
                break;
            }
            case StateMachine::typeKey:
                stackObject = std::make_unique<StateMachineImporter>(
                    object->as<StateMachine>());
                break;
            case StateMachineLayer::typeKey:
            {
                auto artboardImporter =
                    importStack.latest<ArtboardImporter>(ArtboardBase::typeKey);
                if (artboardImporter == nullptr)
                {
                    return ImportResult::malformed;
                }

                stackObject = std::make_unique<StateMachineLayerImporter>(
                    object->as<StateMachineLayer>(),
                    artboardImporter->artboard());

                break;
            }
            case EntryState::typeKey:
            case ExitState::typeKey:
            case AnyState::typeKey:
            case AnimationState::typeKey:
            case BlendState1DViewModel::typeKey:
            case BlendState1DInput::typeKey:
            case BlendStateDirect::typeKey:
                stackObject = std::make_unique<LayerStateImporter>(
                    object->as<LayerState>());
                stackType = LayerState::typeKey;
                break;
            case StateTransition::typeKey:
            case BlendStateTransition::typeKey:
                stackObject = std::make_unique<StateTransitionImporter>(
                    object->as<StateTransition>());
                stackType = StateTransition::typeKey;
                break;
            case StateMachineListener::typeKey:
            case StateMachineListenerSingle::typeKey:
                stackObject = std::make_unique<StateMachineListenerImporter>(
                    object->as<StateMachineListener>());
                stackType = StateMachineListener::typeKey;
                break;
            case ImageAsset::typeKey:
            case FontAsset::typeKey:
            case AudioAsset::typeKey:
            case BlobAsset::typeKey:
                stackObject =
                    std::make_unique<FileAssetImporter>(object->as<FileAsset>(),
                                                        m_assetLoader,
                                                        m_factory);
                stackType = FileAsset::typeKey;
                break;
            case ListenerInputTypeKeyboardBase::typeKey:
                stackObject =
                    std::make_unique<ListenerInputTypeKeyboardImporter>(
                        object->as<ListenerInputTypeKeyboard>());
                stackType = ListenerInputTypeKeyboardBase::typeKey;
                break;
            case ListenerInputTypeGamepadBase::typeKey:
                stackObject =
                    std::make_unique<ListenerInputTypeGamepadImporter>(
                        object->as<ListenerInputTypeGamepad>());
                stackType = ListenerInputTypeGamepadBase::typeKey;
                break;
            case ListenerInputTypeSemanticBase::typeKey:
                stackObject =
                    std::make_unique<ListenerInputTypeSemanticImporter>(
                        object->as<ListenerInputTypeSemantic>());
                stackType = ListenerInputTypeSemanticBase::typeKey;
                break;
#ifdef WITH_RIVE_SCRIPTING
            case ScriptAsset::typeKey:
            {
                auto scriptAsset = object->as<ScriptAsset>();
                stackObject =
                    std::make_unique<TextAssetImporter>(scriptAsset,
                                                        m_assetLoader,
                                                        m_factory,
                                                        &inBandContent);
                stackType = FileAsset::typeKey;
                scriptAsset->file(this);
                break;
            }
            case ScriptModuleAsset::typeKey:
            {
                stackObject = std::make_unique<TextAssetImporter>(
                    object->as<ScriptModuleAsset>(),
                    m_assetLoader,
                    m_factory,
                    &inBandContent);
                stackType = FileAsset::typeKey;
                break;
            }
            case ShaderAsset::typeKey:
            {
                auto shaderAsset = object->as<ShaderAsset>();
                stackObject =
                    std::make_unique<TextAssetImporter>(shaderAsset,
                                                        m_assetLoader,
                                                        m_factory,
                                                        &inBandContent);
                stackType = FileAsset::typeKey;
                break;
            }
#endif
            case ManifestAsset::typeKey:
                stackObject =
                    std::make_unique<FileAssetImporter>(object->as<FileAsset>(),
                                                        m_assetLoader,
                                                        m_factory);
                stackType = FileAsset::typeKey;
                m_manifest = rcp<FileAsset>(object->as<ManifestAsset>());
                break;
            case ViewModel::typeKey:
            {
                stackObject = std::make_unique<ViewModelImporter>(
                    object->as<ViewModel>());
                stackType = ViewModel::typeKey;
                object->as<ViewModel>()->file(this);
                break;
            }
            case ViewModelInstance::typeKey:
                stackObject = std::make_unique<ViewModelInstanceImporter>(
                    object->as<ViewModelInstance>());
                stackType = ViewModelInstance::typeKey;
                break;
            case ViewModelInstanceList::typeKey:
                stackObject = std::make_unique<ViewModelInstanceListImporter>(
                    object->as<ViewModelInstanceList>());
                stackType = ViewModelInstanceList::typeKey;
                break;
            case TransitionViewModelCondition::typeKey:
            case TransitionArtboardCondition::typeKey:
            case TransitionFocusCondition::typeKey:
                stackObject =
                    std::make_unique<TransitionViewModelConditionImporter>(
                        object->as<TransitionViewModelCondition>());
                stackType = TransitionViewModelCondition::typeKey;
                break;
            case BindablePropertyNumber::typeKey:
            case BindablePropertyString::typeKey:
            case BindablePropertyColor::typeKey:
            case BindablePropertyEnum::typeKey:
            case BindablePropertyBoolean::typeKey:
            case BindablePropertyAsset::typeKey:
            case BindablePropertyViewModel::typeKey:
            case BindablePropertyArtboard::typeKey:
            case BindablePropertyTrigger::typeKey:
            case BindablePropertyInteger::typeKey:
            case BindablePropertyList::typeKey:
                stackObject = std::make_unique<BindablePropertyImporter>(
                    object->as<BindableProperty>());
                stackType = BindablePropertyBase::typeKey;
                break;
            case DataConverterGroupBase::typeKey:
                stackObject = std::make_unique<DataConverterGroupImporter>(
                    object->as<DataConverterGroup>());
                stackType = DataConverterGroupBase::typeKey;
                break;
            case DataConverterFormulaBase::typeKey:
                stackObject = std::make_unique<DataConverterFormulaImporter>(
                    object->as<DataConverterFormula>());
                stackType = DataConverterFormulaBase::typeKey;
                break;
            case DataConverterNumberToList::typeKey:
                object->as<DataConverterNumberToList>()->file(this);
                break;
            case ArtboardComponentList::typeKey:
                object->as<ArtboardComponentList>()->file(this);
                break;
            case NestedArtboard::typeKey:
            case NestedArtboardLayout::typeKey:
            case NestedArtboardLeaf::typeKey:
                object->as<NestedArtboard>()->file(this);
                break;
            case ScriptedDataConverter::typeKey:
            case ScriptedDrawable::typeKey:
            case ScriptedLayout::typeKey:
            case ScriptedPathEffect::typeKey:
            case ScriptedListenerAction::typeKey:
            case ScriptedTransitionCondition::typeKey:
            case ScriptedInterpolator::typeKey:
            {
                auto scriptedObject = ScriptedObject::from(object);
                if (scriptedObject != nullptr)
                {
                    stackObject = std::make_unique<ScriptedObjectImporter>(
                        scriptedObject);
                    stackType = ScriptedDrawable::typeKey;
                }
                break;
            }
            case DataBindPathBase::typeKey:
                stackObject = std::make_unique<DataBindPathImporter>(
                    object->as<DataBindPath>());
                stackType = DataBindPathBase::typeKey;
                break;
            case ScriptInputArtboard::typeKey:
                object->as<ScriptInputArtboard>()->file(this);
                break;
        }
        if (importStack.makeLatest(stackType, std::move(stackObject)) !=
            StatusCode::Ok)
        {
            // Some previous stack item didn't resolve.
            return ImportResult::malformed;
        }
        if (object->is<StateMachineLayerComponent>() &&
            importStack.makeLatest(
                StateMachineLayerComponent::typeKey,
                std::make_unique<StateMachineLayerComponentImporter>(
                    object->as<StateMachineLayerComponent>())) !=
                StatusCode::Ok)
        {
            return ImportResult::malformed;
        }
        if (object->is<DataConverter>())
        {
            m_DataConverters.push_back(object->as<DataConverter>());
        }
        else if (object->is<KeyFrameInterpolator>())
        {
            // The file only owns the interpolators that don't belong to a
            // specific artboard
            auto artboardImporter =
                importStack.latest<ArtboardImporter>(ArtboardBase::typeKey);
            if (artboardImporter == nullptr)
            {
                m_keyframeInterpolators.push_back(
                    object->as<KeyFrameInterpolator>());
            }
            if (object->is<ScriptedInterpolator>())
            {
                m_scriptedInterpolators.push_back(
                    object->as<ScriptedInterpolator>());
            }
        }
        else if (object->is<ScrollPhysics>())
        {
            m_scrollPhysics.push_back(object->as<ScrollPhysics>());
        }
    }

    auto resolved = importStack.resolve();
#ifdef WITH_RIVE_SCRIPTING
    registerScripts();
#endif
    return !reader.hasError() && resolved == StatusCode::Ok
               ? ImportResult::success
               : ImportResult::malformed;
}

void File::addFileViewModelInstance(ViewModelInstance* viewModelInstance)
{
    m_ViewModelInstances.push_back(rcp<ViewModelInstance>(viewModelInstance));
}

#ifdef WITH_RIVE_SCRIPTING
#ifdef WITH_RIVE_SCRIPTING_WASM
const char* File::frameBoundary()
{
    const char* warning = nullptr;
    for (auto& vm : m_wasmVMs)
    {
        const char* notice = vm->frameBoundary();
        if (warning == nullptr)
        {
            warning = notice;
        }
    }
    return warning;
}
#endif

void File::registerScripts()
{
#ifdef WITH_RIVE_SCRIPTING_WASM
    // A wasm script module supersedes the bytecode path: scripts live inside
    // the module and ScriptAssets are metadata-only routing records. Assets
    // arrive grouped, each module followed by its scripts; scripts before the
    // first module belong to it, which keeps older single-module files
    // working.
    auto registerOn = [](WasmScriptingVM* vm, ScriptAsset* script) {
        int resultRef = 0;
        if (!vm->requireModule(script->moduleName(), &resultRef))
        {
            fprintf(stderr,
                    "wasm script module '%s' failed: %s\n",
                    script->moduleName().c_str(),
                    vm->lastError().c_str());
        }
        else if (!script->isModule() && resultRef != 0)
        {
            // The module's result is the protocol script's generator;
            // storing the ref lets the standard lazy instantiation flow
            // run against the wasm backend.
            script->registrationComplete(resultRef);
        }
        script->wasmBackend(vm);
    };
    std::vector<ScriptAsset*> pending;
    WasmScriptingVM* current = nullptr;
    for (auto& asset : m_fileAssets)
    {
        if (asset->is<ScriptModuleAsset>())
        {
            auto module = asset->as<ScriptModuleAsset>();
#ifndef WITH_RIVE_TOOLS
            if (!module->verified())
            {
                continue;
            }
#endif
            std::string error;
            auto vm = WasmScriptingVM::make(module->module(), m_factory, error);
            if (vm == nullptr)
            {
                fprintf(stderr,
                        "wasm script module failed to start: %s\n",
                        error.c_str());
                continue;
            }
            vm->viewModels(&m_ViewModels);
            vm->file(this);
            current = vm.get();
            m_wasmVMs.push_back(std::move(vm));
            for (auto* script : pending)
            {
                registerOn(current, script);
            }
            pending.clear();
        }
        else if (asset->is<ScriptAsset>() && current == nullptr)
        {
            pending.push_back(asset->as<ScriptAsset>());
        }
        else if (asset->is<ScriptAsset>())
        {
            registerOn(current, asset->as<ScriptAsset>());
        }
    }
    // Bytecode-only files can still run on the wasm backend: with
    // RIVE_WASM_VM naming a stock vm module, every script registers
    // dynamically instead of arriving baked into a module asset. Dev and
    // sweep-harness lane; bytecode is interpreted by the module's Luau VM.
    if (m_wasmVMs.empty() && !pending.empty())
    {
        if (const char* vmPath = getenv("RIVE_WASM_VM"))
        {
            FILE* vmFile = fopen(vmPath, "rb");
            if (vmFile != nullptr)
            {
                fseek(vmFile, 0, SEEK_END);
                long size = ftell(vmFile);
                fseek(vmFile, 0, SEEK_SET);
                std::vector<uint8_t> vmBytes(size);
                size_t read = fread(vmBytes.data(), 1, size, vmFile);
                fclose(vmFile);
                std::string error;
                auto vm = WasmScriptingVM::make(
                    Span<const uint8_t>(vmBytes.data(), read),
                    m_factory,
                    error);
                if (vm == nullptr)
                {
                    fprintf(stderr,
                            "wasm bytecode lane failed to start: %s\n",
                            error.c_str());
                }
                else
                {
                    vm->viewModels(&m_ViewModels);
                    vm->file(this);
                    current = vm.get();
                    m_wasmVMs.push_back(std::move(vm));
                    for (auto* script : pending)
                    {
                        current->registerBytecode(script->moduleName(),
                                                  script->moduleBytecode());
                    }
                    for (auto* script : pending)
                    {
                        registerOn(current, script);
                    }
                }
            }
        }
    }
    if (!m_wasmVMs.empty())
    {
        return;
    }
#endif

#ifdef WITH_RIVE_SCRIPTING_LUAU
    // Check if we have any script assets in the file
    std::vector<ScriptAsset*> scripts;
    for (auto asset : m_fileAssets)
    {
        if (asset->is<ScriptAsset>())
        {
            scripts.push_back(asset->as<ScriptAsset>());
        }
    }
    // Only make the ScriptingVM if we have any script assets
    if (!scripts.empty())
    {
        // If no VM was provided (e.g., from editor), create our own.
        if (m_scriptingVM == nullptr)
        {
            makeScriptingVM();
        }

        ScriptingVM* vm = m_scriptingVM.get();
        if (vm != nullptr)
        {
            routeScriptingToImportFactory(vm->context());
            // Set up the Data global (view model constructors) on the active
            // VM, whether it was created here or supplied externally (e.g. by
            // the CommandServer). Skip it when the VM's owner builds Data
            // itself, as the editor does in Dart.
            if (!vm->context()->initializesDataGlobalExternally())
            {
                initializeLuaData(vm->state(), m_ViewModels);
            }
            for (auto scriptAsset : scripts)
            {
                // At runtime, if the script is verified, add it to be
                // registered with the VM. At edit time, the script will
                // have already been registered, so this won't run.
                // WITH_RIVE_TOOLS allows unverified scripts for testing.
#ifdef WITH_RIVE_TOOLS
                vm->addModule(scriptAsset);
#else
                if (scriptAsset->verified())
                {
                    vm->addModule(scriptAsset);
                }
#endif
            }
            // Perform registration - ScriptingContext will handle dependencies
            // and retries
            vm->performRegistration();
        }

        for (auto& interpolator : m_scriptedInterpolators)
        {
            auto scriptAsset = interpolator->scriptAsset();
            if (scriptAsset != nullptr)
            {
                scriptAsset->initScriptedObject(interpolator);
            }
        }
    }
#endif
}

#ifdef WITH_RIVE_SCRIPTING_LUAU
// Scripts reach the GPU through their ScriptingContext, and nothing else in
// the import path hands them one, so a script that opened a gpuCanvas used to
// fail on every runtime host. Ore and canvas host routing derive from the
// context's own factory at read time, so route by making that factory the one
// the file imported through, ahead of performRegistration since registration
// can run script bodies.
void File::routeScriptingToImportFactory(ScriptingContext* context)
{
    if (context == nullptr || m_factory == nullptr)
    {
        return;
    }
    // A VM the caller handed in was built before decode chose a recording
    // session, so its scripts would draw to the driver while the file records.
    if (context->factory() != m_factory)
    {
        context->adoptImportFactory(m_factory);
    }
    // The render context has its own late bind flag, and a caller that already
    // satisfied it outranks the factory's default.
    if (context->renderContextIsLateBound())
    {
        if (Factory* renderContext = m_factory->renderContext())
        {
            context->setRenderContext(renderContext);
        }
    }
}

void File::makeScriptingVM()
{
    cleanupScriptingVM();
    auto context = std::make_unique<CPPRuntimeScriptingContext>(m_factory);
    m_scriptingVM = make_rcp<ScriptingVM>(std::move(context));
}

lua_State* File::scriptingState()
{
    return m_scriptingVM ? m_scriptingVM->state() : nullptr;
}

void File::setScriptingVM(rcp<ScriptingVM> vm)
{
#ifdef WITH_RIVE_TOOLS
    if (m_scriptingVM != nullptr)
    {
        ScriptingContext* context = m_scriptingVM->context();
        if (context != nullptr)
        {
            context->disposeOrphanScriptedProperties();
        }
    }
#endif
    m_scriptingVM = std::move(vm);
}

void File::cleanupScriptingVM()
{
#ifdef WITH_RIVE_TOOLS
    if (m_scriptingVM != nullptr)
    {
        ScriptingContext* context = m_scriptingVM->context();
        if (context != nullptr)
        {
            context->disposeOrphanScriptedProperties();
        }
    }
#endif
    // ScriptedObjects only hold a raw ScriptingVM* (see
    // ScriptingVM::registerScriptedObject), so dropping our rcp here is the
    // only thing keeping the VM alive from File's side. If Dart still holds
    // its own rcp<ScriptingVM> (editor flow), the VM and lua_State stay
    // alive until Dart releases too. ~ScriptingVM handles lua_close.
    m_scriptingVM = nullptr;
}
#endif
#endif

Artboard* File::artboard(std::string name) const
{
    for (const auto& artboard : m_artboards)
    {
        if (artboard->name() == name)
        {
            return artboard;
        }
    }
    return nullptr;
}

Artboard* File::artboard() const
{
    if (m_artboards.empty())
    {
        return nullptr;
    }
    return m_artboards[0];
}

Artboard* File::artboard(size_t index) const
{
    if (index >= m_artboards.size())
    {
        return nullptr;
    }
    return m_artboards[index];
}

std::string File::artboardNameAt(size_t index) const
{
    auto ab = this->artboard(index);
    return ab ? ab->name() : "";
}

std::unique_ptr<ArtboardInstance> File::instanceArtboard(Artboard* ab) const
{
    if (ab)
    {
        auto artboardInstance = ab->instance();
#ifdef WITH_RIVE_SCRIPTING_LUAU
        artboardInstance->scriptingVM(m_scriptingVM);
#endif
        artboardInstance->file(ref_rcp(this));

        // Root instances own the FocusManager for their whole tree; nested
        // artboards and component-list items adopt it. Established here rather
        // than by the first state machine so the manager outlives every state
        // machine built against it, and so the tree is built once instead of
        // rebuilt per state machine.
        artboardInstance->buildFocusTree(artboardInstance->ensureFocusManager(),
                                         nullptr);

        // Global view model instances are no longer auto-created here. Callers
        // (e.g. the high-level runtime's autoBind, or explicit
        // setGlobalViewModelInstance) create and bind them on demand.

        return artboardInstance;
    }
    return nullptr;
}

std::unique_ptr<ArtboardInstance> File::artboardDefault() const
{
    auto ab = this->artboard();
    return instanceArtboard(ab);
}

std::unique_ptr<ArtboardInstance> File::artboardAt(size_t index) const
{
    auto ab = this->artboard(index);
    return instanceArtboard(ab);
}

std::unique_ptr<ArtboardInstance> File::artboardNamed(std::string name) const
{
    auto ab = this->artboard(name);
    return instanceArtboard(ab);
}

rcp<BindableArtboard> File::bindableArtboardNamed(std::string name) const
{
    auto ab = this->artboardNamed(name);
    return ab ? make_rcp<BindableArtboard>(ref_rcp(this), std::move(ab))
              : nullptr;
}

rcp<BindableArtboard> File::bindableArtboardDefault() const
{
    auto ab = this->artboardDefault();
    return ab ? make_rcp<BindableArtboard>(ref_rcp(this), std::move(ab))
              : nullptr;
}

rcp<BindableArtboard> File::internalBindableArtboardFromArtboard(
    Artboard* artboard) const
{
    auto ab = artboard ? artboard->instance() : nullptr;
    return ab ? make_rcp<BindableArtboard>(nullptr, std::move(ab)) : nullptr;
}

void File::completeViewModelInstance(
    rcp<ViewModelInstance> viewModelInstance) const
{
    std::unordered_map<ViewModelInstance*, rcp<ViewModelInstance>> instancesMap;
    completeViewModelInstance(viewModelInstance, instancesMap);
}

void File::completeViewModelInstance(
    rcp<ViewModelInstance> viewModelInstance,
    std::unordered_map<ViewModelInstance*, rcp<ViewModelInstance>>&
        instancesMap) const
{
    auto viewModel = m_ViewModels[viewModelInstance->viewModelId()];
    auto propertyValues = viewModelInstance->propertyValues();
    for (auto& value : propertyValues)
    {
        if (value->is<ViewModelInstanceViewModel>())
        {
            auto property = viewModel->property(value->viewModelPropertyId());
            if (property->is<ViewModelPropertyViewModel>())
            {
                auto valueViewModel = value->as<ViewModelInstanceViewModel>();
                auto propertViewModel =
                    property->as<ViewModelPropertyViewModel>();
                auto viewModelReference =
                    m_ViewModels[propertViewModel->viewModelReferenceId()];
                auto viewModelReferenceInstance = viewModelReference->instance(
                    valueViewModel->propertyValue());
                valueViewModel->parentViewModelInstance(
                    viewModelInstance.get());
                if (viewModelReferenceInstance != nullptr)
                {
                    auto itr = instancesMap.find(viewModelReferenceInstance);

                    if (itr == instancesMap.end())
                    {
                        auto viewModelReferenceInstanceCopy =
                            copyViewModelInstance(viewModelReferenceInstance,
                                                  instancesMap);
                        instancesMap[viewModelReferenceInstance] =
                            viewModelReferenceInstanceCopy;
                        valueViewModel->referenceViewModelInstance(
                            viewModelReferenceInstanceCopy);
                    }
                    else
                    {
                        valueViewModel->referenceViewModelInstance(itr->second);
                    }
                }
            }
        }
        else if (value->is<ViewModelInstanceList>())
        {
            auto viewModelList = value->as<ViewModelInstanceList>();
            viewModelList->parentViewModelInstance(viewModelInstance.get());
            for (auto& listItem : viewModelList->listItems())
            {
                auto viewModel = m_ViewModels[listItem->viewModelId()];
                auto viewModelListItemInstance =
                    viewModel->instance(listItem->viewModelInstanceId());
                if (viewModelListItemInstance != nullptr)
                {

                    auto itr = instancesMap.find(viewModelListItemInstance);

                    if (itr == instancesMap.end())
                    {
                        auto viewModelInstanceListItemCopy =
                            copyViewModelInstance(viewModelListItemInstance,
                                                  instancesMap);
                        instancesMap[viewModelListItemInstance] =
                            viewModelInstanceListItemCopy;
                        listItem->viewModelInstance(
                            viewModelInstanceListItemCopy);
                    }
                    else
                    {
                        listItem->viewModelInstance(itr->second);
                    }
                }
            }
        }
        value->viewModelProperty(
            viewModel->property(value->viewModelPropertyId()));
    }
}

void File::completeViewModelProperties(ViewModelInstance* viewModelInstance)
{
    auto viewModel = m_ViewModels[viewModelInstance->viewModelId()];
    auto propertyValues = viewModelInstance->propertyValues();
    for (auto& value : propertyValues)
    {
        if (value->is<ViewModelInstanceViewModel>())
        {
            auto property = viewModel->property(value->viewModelPropertyId());
            if (property->is<ViewModelPropertyViewModel>())
            {
                auto valueViewModel = value->as<ViewModelInstanceViewModel>();
                auto propertViewModel =
                    property->as<ViewModelPropertyViewModel>();
                auto viewModelReference =
                    m_ViewModels[propertViewModel->viewModelReferenceId()];
                auto viewModelReferenceInstance = viewModelReference->instance(
                    valueViewModel->propertyValue());
                if (viewModelReferenceInstance != nullptr)
                {
                    completeViewModelProperties(viewModelReferenceInstance);
                }
            }
        }
        else if (value->is<ViewModelInstanceList>())
        {
            auto viewModelList = value->as<ViewModelInstanceList>();
            for (auto& listItem : viewModelList->listItems())
            {
                auto viewModel = m_ViewModels[listItem->viewModelId()];
                auto viewModelListItemInstance =
                    viewModel->instance(listItem->viewModelInstanceId());
                if (viewModelListItemInstance != nullptr)
                {
                    completeViewModelProperties(viewModelListItemInstance);
                }
            }
        }
        value->viewModelProperty(
            viewModel->property(value->viewModelPropertyId()));
    }
}

rcp<ViewModelInstance> File::copyViewModelInstance(
    ViewModelInstance* viewModelInstance,
    std::unordered_map<ViewModelInstance*, rcp<ViewModelInstance>>&
        instancesMap) const
{
    auto copy = rcp<ViewModelInstance>(
        viewModelInstance->clone()->as<ViewModelInstance>());
    completeViewModelInstance(copy, instancesMap);
#ifdef WITH_RIVE_TOOLS
    if (copy)
    {
        registerViewModelInstance(copy.get(), copy);
    }
#endif
    return copy;
}

rcp<ViewModelInstance> File::createViewModelInstance(std::string name) const
{
    for (auto& viewModel : m_ViewModels)
    {
        if (viewModel->is<ViewModel>())
        {
            if (viewModel->name() == name)
            {
                return createViewModelInstance(viewModel);
            }
        }
    }
    return nullptr;
}

rcp<ViewModelInstance> File::createViewModelInstance(
    const std::string& name,
    const std::string& instanceName) const
{
    for (auto& viewModel : m_ViewModels)
    {
        if (viewModel->name() == name)
        {
            auto instance = viewModel->instance(instanceName);
            if (instance != nullptr)
            {
                std::unordered_map<ViewModelInstance*, rcp<ViewModelInstance>>
                    instancesMap;
                return copyViewModelInstance(instance, instancesMap);
            }
        }
    }
    return nullptr;
}

rcp<ViewModelInstance> File::createViewModelInstance(size_t index,
                                                     size_t instanceIndex) const
{
    if (index < m_ViewModels.size())
    {
        auto viewModel = m_ViewModels[index];
        auto instance = viewModel->instance(instanceIndex);
        if (instance != nullptr)
        {
            std::unordered_map<ViewModelInstance*, rcp<ViewModelInstance>>
                instancesMap;
            return copyViewModelInstance(instance, instancesMap);
        }
    }
    return nullptr;
}

uint32_t File::findViewModelId(ViewModel* search) const
{
    uint32_t viewModelId = 0;
    for (auto& viewModel : m_ViewModels)
    {
        if (viewModel == search)
        {
            break;
        }
        viewModelId++;
    }
    return viewModelId;
}

#ifdef WITH_RIVE_TOOLS
void File::setViewModelInstanceRegistrar(ViewModelInstanceRegistrar* registrar)
{
    m_viewModelInstanceRegistrar = registrar;
}

void File::registerViewModelInstance(ViewModelInstance* ptr,
                                     rcp<ViewModelInstance> ref) const
{
    if (ptr != nullptr && m_viewModelInstanceRegistrar != nullptr)
    {
        m_viewModelInstanceRegistrar->registerInstance(ptr, std::move(ref));
    }
}

bool File::containsViewModelInstance(ViewModelInstance* ptr) const
{
    return m_viewModelInstanceRegistrar != nullptr &&
           m_viewModelInstanceRegistrar->contains(ptr);
}

void File::clearRuntimeViewModelInstances()
{
    if (m_viewModelInstanceRegistrar != nullptr)
    {
        m_viewModelInstanceRegistrar->clear();
    }
}
#endif

rcp<ViewModelInstance> File::createViewModelInstance(ViewModel* viewModel) const
{
    if (viewModel != nullptr)
    {
        uint32_t viewModelId = findViewModelId(viewModel);

        auto viewModelInstance = new ViewModelInstance();
        viewModelInstance->viewModelId(viewModelId);
        viewModelInstance->viewModel(viewModel);
        auto properties = viewModel->properties();
        uint32_t propertyId = 0;
        for (auto& property : properties)
        {
            ViewModelInstanceValue* viewModelInstanceValue = nullptr;
            switch (property->coreType())
            {
                case ViewModelPropertyStringBase::typeKey:
                    viewModelInstanceValue = new ViewModelInstanceString();
                    break;
                case ViewModelPropertyNumberBase::typeKey:
                    viewModelInstanceValue = new ViewModelInstanceNumber();
                    break;
                case ViewModelPropertyBooleanBase::typeKey:
                    viewModelInstanceValue = new ViewModelInstanceBoolean();
                    break;
                case ViewModelPropertyColorBase::typeKey:
                    viewModelInstanceValue = new ViewModelInstanceColor();
                    break;
                case ViewModelPropertyListBase::typeKey:
                    viewModelInstanceValue = new ViewModelInstanceList();
                    viewModelInstanceValue->as<ViewModelInstanceList>()
                        ->parentViewModelInstance(viewModelInstance);
                    break;
                case ViewModelPropertyEnumSystemBase::typeKey:
                case ViewModelPropertyEnumCustomBase::typeKey:
                case ViewModelPropertyEnumBase::typeKey:
                    viewModelInstanceValue = new ViewModelInstanceEnum();
                    break;
                case ViewModelPropertyTriggerBase::typeKey:
                    viewModelInstanceValue = new ViewModelInstanceTrigger();
                    break;
                case ViewModelPropertyViewModelBase::typeKey:
                {
                    viewModelInstanceValue = new ViewModelInstanceViewModel();
                    auto propertViewModel =
                        property->as<ViewModelPropertyViewModel>();
                    auto viewModelReference =
                        m_ViewModels[propertViewModel->viewModelReferenceId()];
                    auto viewModelInstanceViewModel =
                        viewModelInstanceValue
                            ->as<ViewModelInstanceViewModel>();
                    auto referenceViewModelInstance =
                        createViewModelInstance(viewModelReference);
                    if (referenceViewModelInstance)
                    {
                        viewModelInstanceViewModel->parentViewModelInstance(
                            viewModelInstance);
                        viewModelInstanceViewModel->referenceViewModelInstance(
                            referenceViewModelInstance);
                    }
                }
                break;
                case ViewModelPropertyAssetImageBase::typeKey:
                    viewModelInstanceValue = new ViewModelInstanceAssetImage();
                    break;
                case ViewModelPropertyAssetFontBase::typeKey:
                    viewModelInstanceValue = new ViewModelInstanceAssetFont();
                    break;
                case ViewModelPropertyAssetBlobBase::typeKey:
                    viewModelInstanceValue = new ViewModelInstanceAssetBlob();
                    break;
                case ViewModelPropertySymbolListIndexBase::typeKey:
                    viewModelInstanceValue =
                        new ViewModelInstanceSymbolListIndex();
                    break;
                case ViewModelPropertyArtboardBase::typeKey:
                    viewModelInstanceValue = new ViewModelInstanceArtboard();
                    break;
                default:
                    fprintf(stderr, "Missing view model property type\n");
                    break;
            }
            if (viewModelInstanceValue != nullptr)
            {
                viewModelInstanceValue->viewModelProperty(property);
                viewModelInstanceValue->viewModelPropertyId(propertyId);
            }
            viewModelInstance->addValue(viewModelInstanceValue);
            propertyId++;
        }
#ifdef WITH_RIVE_TOOLS
        if (viewModelInstance)
        {
            auto result = rcp<ViewModelInstance>(viewModelInstance);
            registerViewModelInstance(viewModelInstance, result);
            return result;
        }
#endif
        return rcp<ViewModelInstance>(viewModelInstance);
    }
    return nullptr;
}

rcp<ViewModelInstance> File::createViewModelInstance(Artboard* artboard) const
{
    if ((size_t)artboard->viewModelId() < m_ViewModels.size())
    {
        auto viewModel = m_ViewModels[artboard->viewModelId()];
        if (viewModel != nullptr)
        {
            return createViewModelInstance(viewModel);
        }
    }
    return nullptr;
}

rcp<ViewModelInstance> File::createDefaultViewModelInstance(
    Artboard* artboard) const
{
    if ((size_t)artboard->viewModelId() < m_ViewModels.size())
    {
        auto viewModel = m_ViewModels[artboard->viewModelId()];
        if (viewModel != nullptr)
        {
            return createDefaultViewModelInstance(viewModel);
        }
    }
    return nullptr;
}

rcp<ViewModelInstance> File::createDefaultViewModelInstance(
    ViewModel* viewModel) const
{
    auto viewModelInstance = viewModel->instance(0);
    if (viewModelInstance != nullptr)
    {
        auto copy = rcp<ViewModelInstance>(
            viewModelInstance->clone()->as<ViewModelInstance>());
        completeViewModelInstance(copy);
#ifdef WITH_RIVE_TOOLS
        if (copy)
        {
            registerViewModelInstance(copy.get(), copy);
        }
#endif
        return copy;
    }
    return createViewModelInstance(viewModel);
}

ViewModelInstanceListItem* File::viewModelInstanceListItem(
    rcp<ViewModelInstance> viewModelInstance)
{
    // Search for an implicit artboard linked to the viewModel.
    // It will return the first one it finds, but there could be more.
    // We should decide if we want to be more restrictive and only return
    // an artboard if one and only one is found.
    for (auto& artboard : m_artboards)
    {
        if (artboard->viewModelId() == viewModelInstance->viewModelId())
        {
            return viewModelInstanceListItem(viewModelInstance, artboard);
        }
    }
    return nullptr;
}

ViewModelInstanceListItem* File::viewModelInstanceListItem(
    rcp<ViewModelInstance> viewModelInstance,
    Artboard* artboard)
{
    auto viewModelInstanceListItem = new ViewModelInstanceListItem();
    viewModelInstanceListItem->viewModelInstance(viewModelInstance);
    viewModelInstanceListItem->artboard(artboard);
    return viewModelInstanceListItem;
}

ViewModel* File::viewModel(std::string name)
{
    for (auto& viewModel : m_ViewModels)
    {
        if (viewModel->name() == name)
        {
            return viewModel;
        }
    }
    return nullptr;
}

ViewModel* File::viewModel(size_t index) const
{
    if (index < m_ViewModels.size())
    {
        return m_ViewModels[index];
    }
    return nullptr;
}

uint32_t File::viewModelId(const std::string& name) const
{
    for (uint32_t i = 0; i < m_ViewModels.size(); i++)
    {
        auto vm = m_ViewModels[i];
        if (vm != nullptr && vm->name() == name)
        {
            return i;
        }
    }
    return static_cast<uint32_t>(m_ViewModels.size());
}

std::vector<ViewModel*> File::globalViewModels() const
{
    std::vector<ViewModel*> viewModels;
    for (ViewModel* vm : m_ViewModels)
    {
        if (vm != nullptr && static_cast<ViewModelType>(vm->viewModelType()) ==
                                 ViewModelType::global)
        {
            viewModels.push_back(vm);
        }
    }
    return viewModels;
}

std::vector<std::string> File::globalViewModelNames() const
{
    std::vector<std::string> names;
    for (ViewModel* vm : globalViewModels())
    {
        names.push_back(vm->name());
    }
    return names;
}

ViewModelRuntime* File::viewModelByIndex(size_t index) const
{
    if (index < m_ViewModels.size())
    {
        return createViewModelRuntime(m_ViewModels[index]).get();
    }
    fprintf(stderr,
            "Could not find View Model. Index %zu is out of range.\n",
            index);
    return nullptr;
}

ViewModelRuntime* File::viewModelByName(std::string name) const
{
    for (auto& viewModel : m_ViewModels)
    {
        if (viewModel->name() == name)
        {
            return createViewModelRuntime(viewModel).get();
        }
    }
    fprintf(stderr, "Could not find View Model named %s.\n", name.c_str());
    return nullptr;
}

ViewModelRuntime* File::defaultArtboardViewModel(Artboard* artboard) const
{
    if (artboard == nullptr)
    {
        return nullptr;
    }
    if ((size_t)artboard->viewModelId() < m_ViewModels.size())
    {
        auto viewModel = m_ViewModels[artboard->viewModelId()];
        return createViewModelRuntime(viewModel).get();
    }
    fprintf(stderr,
            "Could not find a View Model linked to Artboard %s.\n",
            artboard->name().c_str());
    return nullptr;
}

rcp<ViewModelRuntime> File::createViewModelRuntime(ViewModel* viewModel) const
{
    auto viewModelRuntime = make_rcp<ViewModelRuntime>(viewModel, this);
    m_viewModelRuntimes.push_back(viewModelRuntime);
    return viewModelRuntime;
}

Span<const rcp<FileAsset>> File::assets() const { return m_fileAssets; }

const std::vector<DataEnum*>& File::enums() const { return m_Enums; }

#ifdef WITH_RIVE_TOOLS
const std::vector<uint8_t> File::stripAssets(Span<const uint8_t> bytes,
                                             std::set<uint16_t> typeKeys,
                                             ImportResult* result)
{
    std::vector<uint8_t> strippedData;
    strippedData.reserve(bytes.size());
    BinaryReader reader(bytes);
    RuntimeHeader header;
    if (!RuntimeHeader::read(reader, header))
    {
        if (result)
        {
            *result = ImportResult::malformed;
        }
    }
    else if (header.majorVersion() != majorVersion)
    {
        if (result)
        {
            *result = ImportResult::unsupportedVersion;
        }
    }
    else
    {
        strippedData.insert(strippedData.end(),
                            bytes.data(),
                            reader.position());
        const uint8_t* from = reader.position();
        const uint8_t* to = reader.position();
        uint16_t lastAssetType = 0;
        while (!reader.reachedEnd())
        {
            auto object = readRuntimeObject(reader, header);
            if (object == nullptr)
            {
                continue;
            }
            if (object->is<FileAssetBase>())
            {
                lastAssetType = object->coreType();
            }
            if (object->is<FileAssetContents>() &&
                typeKeys.find(lastAssetType) != typeKeys.end())
            {
                if (from != to)
                {
                    strippedData.insert(strippedData.end(), from, to);
                }
                from = reader.position();
            }
            delete object;
            to = reader.position();
        }
        if (from != to)
        {
            strippedData.insert(strippedData.end(), from, to);
        }
        *result = ImportResult::success;
    }
    return strippedData;
}

#endif

rcp<FileAsset> File::asset(size_t index)
{
    if (index >= 0 && index < m_fileAssets.size())
    {
        return m_fileAssets[index];
    }
    return nullptr;
}
