#include "ComponentsRegistry.h"

#if !__has_include(<DefaultTurboModuleManagerDelegate.h>)

#include "AutolinkingCompat.h"

#if __has_include(<react/fabric/CoreComponentsRegistry.h>)  // >= 0.71
#include <react/fabric/CoreComponentsRegistry.h>
#else  // < 0.71
#include <CoreComponentsRegistry.h>
#endif  // __has_include(<react/fabric/CoreComponentsRegistry.h>)

#include <DefaultComponentsRegistry.h>

#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
#include <react/renderer/componentregistry/ComponentDescriptorRegistry.h>
#include <react/renderer/components/rncore/ComponentDescriptors.h>

using facebook::react::ComponentDescriptorParameters;
using facebook::react::ComponentDescriptorProviderRegistry;
using facebook::react::ComponentDescriptorRegistry;
using facebook::react::ComponentFactory;
using facebook::react::ContextContainer;
using facebook::react::CoreComponentsRegistry;
using facebook::react::EventDispatcher;
using facebook::react::UnimplementedNativeViewComponentDescriptor;
using ReactTestApp::ComponentsRegistry;

void ComponentsRegistry::registerNatives()
{
    registerHybrid({makeNativeMethod("initHybrid", ComponentsRegistry::initHybrid)});

    facebook::react::DefaultComponentsRegistry::registerComponentDescriptorsFromEntryPoint =
        [](std::shared_ptr<ComponentDescriptorProviderRegistry const> registry) {
            // Register providers generated by `@react-native-community/cli`
            autolinking_registerProviders(registry);
        };
}

ComponentsRegistry::ComponentsRegistry(ComponentFactory *)
{
}

facebook::jni::local_ref<ComponentsRegistry::jhybriddata>
ComponentsRegistry::initHybrid(facebook::jni::alias_ref<jclass>, ComponentFactory *delegate)
{
    delegate->buildRegistryFunction = [](EventDispatcher::Weak const &eventDispatcher,
                                         ContextContainer::Shared const &contextContainer)
        -> ComponentDescriptorRegistry::Shared {
        auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry();

        auto registry = providerRegistry->createComponentDescriptorRegistry(
            {eventDispatcher, contextContainer});

        auto mutableRegistry = std::const_pointer_cast<ComponentDescriptorRegistry>(registry);

        mutableRegistry->setFallbackComponentDescriptor(
            std::make_shared<UnimplementedNativeViewComponentDescriptor>(
                ComponentDescriptorParameters{eventDispatcher, contextContainer, nullptr}));

        return registry;
    };

    return makeCxxInstance(delegate);
}

#endif  // !__has_include(<DefaultTurboModuleManagerDelegate.h>)
