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

import org.apache.logging.log4j.LogManager;
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
import net.minecraft.Util;
import net.minecraft.world.level.block.entity.BlockEntity;
import java.util.Iterator;
import net.minecraft.world.level.material.Material;
import net.minecraft.world.level.block.entity.SpawnerBlockEntity;
import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity;
import net.minecraft.world.level.storage.loot.BuiltInLootTables;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.levelgen.structure.StructurePiece;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.core.BlockPos;
import java.util.Random;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.StructureFeatureManager;
import net.minecraft.world.level.WorldGenLevel;
import com.mojang.serialization.Codec;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.entity.EntityType;
import org.apache.logging.log4j.Logger;
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;

public class MonsterRoomFeature extends Feature<NoneFeatureConfiguration> {
    private static final Logger LOGGER;
    private static final EntityType<?>[] MOBS;
    private static final BlockState AIR;
    
    public MonsterRoomFeature(final Codec<NoneFeatureConfiguration> codec) {
        super(codec);
    }
    
    @Override
    public boolean place(final WorldGenLevel bqu, final StructureFeatureManager bqq, final ChunkGenerator cha, final Random random, final BlockPos fu, final NoneFeatureConfiguration coa) {
        final int integer8 = 3;
        final int integer9 = random.nextInt(2) + 2;
        final int integer10 = -integer9 - 1;
        final int integer11 = integer9 + 1;
        final int integer12 = -1;
        final int integer13 = 4;
        final int integer14 = random.nextInt(2) + 2;
        final int integer15 = -integer14 - 1;
        final int integer16 = integer14 + 1;
        int integer17 = 0;
        for (int integer18 = integer10; integer18 <= integer11; ++integer18) {
            for (int integer19 = -1; integer19 <= 4; ++integer19) {
                for (int integer20 = integer15; integer20 <= integer16; ++integer20) {
                    final BlockPos fu2 = fu.offset(integer18, integer19, integer20);
                    final Material cxd22 = bqu.getBlockState(fu2).getMaterial();
                    final boolean boolean23 = cxd22.isSolid();
                    if (integer19 == -1 && !boolean23) {
                        return false;
                    }
                    if (integer19 == 4 && !boolean23) {
                        return false;
                    }
                    if ((integer18 == integer10 || integer18 == integer11 || integer20 == integer15 || integer20 == integer16) && integer19 == 0 && bqu.isEmptyBlock(fu2) && bqu.isEmptyBlock(fu2.above())) {
                        ++integer17;
                    }
                }
            }
        }
        if (integer17 < 1 || integer17 > 5) {
            return false;
        }
        for (int integer18 = integer10; integer18 <= integer11; ++integer18) {
            for (int integer19 = 3; integer19 >= -1; --integer19) {
                for (int integer20 = integer15; integer20 <= integer16; ++integer20) {
                    final BlockPos fu2 = fu.offset(integer18, integer19, integer20);
                    final BlockState cfj22 = bqu.getBlockState(fu2);
                    if (integer18 == integer10 || integer19 == -1 || integer20 == integer15 || integer18 == integer11 || integer19 == 4 || integer20 == integer16) {
                        if (fu2.getY() >= 0 && !bqu.getBlockState(fu2.below()).getMaterial().isSolid()) {
                            bqu.setBlock(fu2, MonsterRoomFeature.AIR, 2);
                        }
                        else if (cfj22.getMaterial().isSolid() && !cfj22.is(Blocks.CHEST)) {
                            if (integer19 == -1 && random.nextInt(4) != 0) {
                                bqu.setBlock(fu2, Blocks.MOSSY_COBBLESTONE.defaultBlockState(), 2);
                            }
                            else {
                                bqu.setBlock(fu2, Blocks.COBBLESTONE.defaultBlockState(), 2);
                            }
                        }
                    }
                    else if (!cfj22.is(Blocks.CHEST) && !cfj22.is(Blocks.SPAWNER)) {
                        bqu.setBlock(fu2, MonsterRoomFeature.AIR, 2);
                    }
                }
            }
        }
        for (int integer18 = 0; integer18 < 2; ++integer18) {
            for (int integer19 = 0; integer19 < 3; ++integer19) {
                final int integer20 = fu.getX() + random.nextInt(integer9 * 2 + 1) - integer9;
                final int integer21 = fu.getY();
                final int integer22 = fu.getZ() + random.nextInt(integer14 * 2 + 1) - integer14;
                final BlockPos fu3 = new BlockPos(integer20, integer21, integer22);
                if (bqu.isEmptyBlock(fu3)) {
                    int integer23 = 0;
                    for (final Direction fz26 : Direction.Plane.HORIZONTAL) {
                        if (bqu.getBlockState(fu3.relative(fz26)).getMaterial().isSolid()) {
                            ++integer23;
                        }
                    }
                    if (integer23 == 1) {
                        bqu.setBlock(fu3, StructurePiece.reorient(bqu, fu3, Blocks.CHEST.defaultBlockState()), 2);
                        RandomizableContainerBlockEntity.setLootTable(bqu, random, fu3, BuiltInLootTables.SIMPLE_DUNGEON);
                        break;
                    }
                }
            }
        }
        bqu.setBlock(fu, Blocks.SPAWNER.defaultBlockState(), 2);
        final BlockEntity cdl18 = bqu.getBlockEntity(fu);
        if (cdl18 instanceof SpawnerBlockEntity) {
            ((SpawnerBlockEntity)cdl18).getSpawner().setEntityId(this.randomEntityId(random));
        }
        else {
            MonsterRoomFeature.LOGGER.error("Failed to fetch mob spawner entity at ({}, {}, {})", fu.getX(), fu.getY(), fu.getZ());
        }
        return true;
    }
    
    private EntityType<?> randomEntityId(final Random random) {
        return Util.<EntityType<?>>getRandom(MonsterRoomFeature.MOBS, random);
    }
    
    static {
        LOGGER = LogManager.getLogger();
        MOBS = new EntityType[] { EntityType.SKELETON, EntityType.ZOMBIE, EntityType.ZOMBIE, EntityType.SPIDER };
        AIR = Blocks.CAVE_AIR.defaultBlockState();
    }
}
