package top.r3944realms.lib39.mixin;

import net.fabricmc.fabric.api.lookup.v1.custom.ApiProviderMap;
import net.fabricmc.fabric.api.lookup.v1.entity.EntityApiLookup;
import net.fabricmc.fabric.impl.lookup.entity.EntityApiLookupImpl;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import top.r3944realms.lib39.core.sync.IEntityApiLookUpImplExtend;

import java.util.List;
import java.util.Objects;

/**
 * The type Mixin api look up.
 *
 * @param <A> the type parameter
 * @param <C> the type parameter
 */
@SuppressWarnings("UnstableApiUsage")
@Mixin(value = EntityApiLookupImpl.class, remap = false)
public class MixinApiLookUpImpl<A, C> implements IEntityApiLookUpImplExtend<A, C> {
    @Shadow @Final private ApiProviderMap<EntityType<?>, EntityApiLookup.EntityApiProvider<A, C>> providerMap;

    @Shadow @Final private List<EntityApiLookup.EntityApiProvider<A, C>> fallbackProviders;

    @Override
    @Nullable
    public A lib39$findWithoutCheck(Entity entity, C context) {
        Objects.requireNonNull(entity, "Entity may not be null.");
        EntityApiLookup.EntityApiProvider<A, C> provider = providerMap.get(entity.getType());

        if (provider != null) {
            A instance = provider.find(entity, context);

            if (instance != null) {
                return instance;
            }
        }

        for (EntityApiLookup.EntityApiProvider<A, C> fallback : fallbackProviders) {
            A instance = fallback.find(entity, context);

            if (instance != null) {
                return instance;
            }
        }
        return null;
    }
}
