package net.minecraft.world.level;

import net.minecraft.world.level.levelgen.structure.StructurePiece;
import java.util.Optional;
import com.mojang.datafixers.DataFixUtils;
import net.minecraft.core.Vec3i;
import net.minecraft.core.BlockPos;
import javax.annotation.Nullable;
import net.minecraft.world.level.chunk.FeatureAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.levelgen.structure.StructureStart;
import java.util.stream.Stream;
import net.minecraft.world.level.levelgen.feature.StructureFeature;
import net.minecraft.core.SectionPos;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.level.levelgen.WorldGenSettings;

public class StructureFeatureManager {
    private final LevelAccessor level;
    private final WorldGenSettings worldGenSettings;
    
    public StructureFeatureManager(final LevelAccessor bqc, final WorldGenSettings cix) {
        this.level = bqc;
        this.worldGenSettings = cix;
    }
    
    public StructureFeatureManager forWorldGenRegion(final WorldGenRegion zj) {
        if (zj.getLevel() != this.level) {
            throw new IllegalStateException("Using invalid feature manager (source level: " + zj.getLevel() + ", region: " + zj);
        }
        return new StructureFeatureManager(zj, this.worldGenSettings);
    }
    
    public Stream<? extends StructureStart<?>> startsForFeature(final SectionPos go, final StructureFeature<?> cml) {
        return this.level.getChunk(go.x(), go.z(), ChunkStatus.STRUCTURE_REFERENCES).getReferencesForFeature(cml).stream().map(long1 -> SectionPos.of(new ChunkPos(long1), 0)).map(go -> this.getStartForFeature(go, cml, this.level.getChunk(go.x(), go.z(), ChunkStatus.STRUCTURE_STARTS))).filter(ctz -> ctz != null && ctz.isValid());
    }
    
    @Nullable
    public StructureStart<?> getStartForFeature(final SectionPos go, final StructureFeature<?> cml, final FeatureAccess chf) {
        return chf.getStartForFeature(cml);
    }
    
    public void setStartForFeature(final SectionPos go, final StructureFeature<?> cml, final StructureStart<?> ctz, final FeatureAccess chf) {
        chf.setStartForFeature(cml, ctz);
    }
    
    public void addReferenceForFeature(final SectionPos go, final StructureFeature<?> cml, final long long3, final FeatureAccess chf) {
        chf.addReferenceForFeature(cml, long3);
    }
    
    public boolean shouldGenerateFeatures() {
        return this.worldGenSettings.generateFeatures();
    }
    
    public StructureStart<?> getStructureAt(final BlockPos fu, final boolean boolean2, final StructureFeature<?> cml) {
        return DataFixUtils.orElse((Optional)this.startsForFeature(SectionPos.of(fu), cml).filter(ctz -> ctz.getBoundingBox().isInside(fu)).filter(ctz -> !boolean2 || ctz.getPieces().stream().anyMatch(cty -> cty.getBoundingBox().isInside(fu))).findFirst(), StructureStart.INVALID_START);
    }
}
