package net.minecraft.world.level.levelgen.feature;

import org.apache.logging.log4j.LogManager;
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.core.BlockPos;
import java.util.Random;
import net.minecraft.world.level.levelgen.ChunkGeneratorSettings;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.LevelAccessor;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
import net.minecraft.core.Registry;
import com.mojang.datafixers.types.DynamicOps;
import net.minecraft.world.level.levelgen.feature.configurations.DecoratedFeatureConfiguration;
import net.minecraft.world.level.levelgen.placement.ConfiguredDecorator;
import com.mojang.datafixers.Dynamic;
import org.apache.logging.log4j.Logger;
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;

public class ConfiguredFeature<FC extends FeatureConfiguration, F extends Feature<FC>> {
    public static final Logger LOGGER;
    public final F feature;
    public final FC config;
    
    public ConfiguredFeature(final F cdu, final FC cgn) {
        this.feature = cdu;
        this.config = cgn;
    }
    
    public ConfiguredFeature(final F cdu, final Dynamic<?> dynamic) {
        this(cdu, ((Feature<FeatureConfiguration>)cdu).createSettings(dynamic));
    }
    
    public ConfiguredFeature<?, ?> decorated(final ConfiguredDecorator<?> cjj) {
        final Feature<DecoratedFeatureConfiguration> cdu3 = (this.feature instanceof AbstractFlowerFeature) ? Feature.DECORATED_FLOWER : Feature.DECORATED;
        return cdu3.configured(new DecoratedFeatureConfiguration(this, cjj));
    }
    
    public WeightedConfiguredFeature<FC> weighted(final float float1) {
        return new WeightedConfiguredFeature<FC>(this, float1);
    }
    
    public <T> Dynamic<T> serialize(final DynamicOps<T> dynamicOps) {
        return (Dynamic<T>)new Dynamic((DynamicOps)dynamicOps, dynamicOps.createMap((Map)ImmutableMap.of(dynamicOps.createString("name"), dynamicOps.createString(Registry.FEATURE.getKey(this.feature).toString()), dynamicOps.createString("config"), this.config.<T>serialize(dynamicOps).getValue())));
    }
    
    public boolean place(final LevelAccessor bjx, final ChunkGenerator<? extends ChunkGeneratorSettings> caa, final Random random, final BlockPos fk) {
        return this.feature.place(bjx, caa, random, fk, this.config);
    }
    
    public static <T> ConfiguredFeature<?, ?> deserialize(final Dynamic<T> dynamic) {
        final String string2 = dynamic.get("name").asString("");
        final Feature<? extends FeatureConfiguration> cdu3 = Registry.FEATURE.get(new ResourceLocation(string2));
        try {
            return new ConfiguredFeature<Object, Object>(cdu3, dynamic.get("config").orElseEmptyMap());
        }
        catch (RuntimeException runtimeException4) {
            ConfiguredFeature.LOGGER.warn("Error while deserializing {}", string2);
            return new ConfiguredFeature<Object, Object>(Feature.NO_OP, NoneFeatureConfiguration.NONE);
        }
    }
    
    static {
        LOGGER = LogManager.getLogger();
    }
}
