package net.minecraft.util.datafix.fixes;

import com.mojang.serialization.DynamicOps;
import java.util.Iterator;
import java.util.stream.Stream;
import com.mojang.datafixers.Typed;
import com.mojang.datafixers.OpticFinder;
import java.util.Map;
import com.mojang.datafixers.util.Pair;
import com.google.common.collect.Maps;
import java.util.function.Function;
import com.google.common.collect.Lists;
import com.mojang.serialization.Dynamic;
import com.mojang.datafixers.DSL;
import com.mojang.datafixers.types.Type;
import com.mojang.datafixers.types.templates.List;
import com.mojang.datafixers.TypeRewriteRule;
import com.mojang.datafixers.schemas.Schema;
import com.mojang.datafixers.DataFix;

public class BedBlockEntityInjecter extends DataFix {
    public BedBlockEntityInjecter(final Schema schema, final boolean boolean2) {
        super(schema, boolean2);
    }
    
    public TypeRewriteRule makeRule() {
        final Type<?> type2 = this.getOutputSchema().getType(References.CHUNK);
        final Type<?> type3 = type2.findFieldType("Level");
        final Type<?> type4 = type3.findFieldType("TileEntities");
        if (!(type4 instanceof List.ListType)) {
            throw new IllegalStateException("Tile entity type is not a list type.");
        }
        final List.ListType<?> listType5 = type4;
        return this.cap(type3, listType5);
    }
    
    private <TE> TypeRewriteRule cap(final Type<?> type, final List.ListType<TE> listType) {
        final Type<TE> type2 = (Type<TE>)listType.getElement();
        final OpticFinder<?> opticFinder5 = DSL.fieldFinder("Level", (Type)type);
        final OpticFinder<java.util.List<TE>> opticFinder6 = (OpticFinder<java.util.List<TE>>)DSL.fieldFinder("TileEntities", (Type)listType);
        final int integer7 = 416;
        final OpticFinder opticFinder7;
        final Typed<?> typed2;
        final Dynamic<?> dynamic2;
        final int integer8;
        final int integer9;
        final OpticFinder opticFinder8;
        final java.util.List<Object> list9;
        java.util.List<? extends Dynamic<?>> list10;
        int integer10;
        Dynamic<?> dynamic3;
        int integer11;
        Stream<Integer> stream14;
        int integer12;
        final Iterator<Integer> iterator;
        int integer13;
        int integer14;
        int integer15;
        int integer16;
        Map<Dynamic<?>, Dynamic<?>> map21;
        final Type type3;
        return TypeRewriteRule.seq(this.fixTypeEverywhere("InjectBedBlockEntityType", (Type)this.getInputSchema().findChoiceType(References.BLOCK_ENTITY), (Type)this.getOutputSchema().findChoiceType(References.BLOCK_ENTITY), dynamicOps -> pair -> pair), this.fixTypeEverywhereTyped("BedBlockEntityInjecter", this.getOutputSchema().getType(References.CHUNK), typed -> {
            typed2 = typed.getTyped(opticFinder7);
            dynamic2 = typed2.get(DSL.remainderFinder());
            integer8 = dynamic2.get("xPos").asInt(0);
            integer9 = dynamic2.get("zPos").asInt(0);
            list9 = Lists.newArrayList(typed2.getOrCreate(opticFinder8));
            for (list10 = dynamic2.get("Sections").asList((Function)Function.identity()), integer10 = 0; integer10 < list10.size(); ++integer10) {
                dynamic3 = list10.get(integer10);
                integer11 = dynamic3.get("Y").asInt(0);
                stream14 = dynamic3.get("Blocks").asStream().<Integer>map(dynamic -> dynamic.asInt(0));
                integer12 = 0;
                ((Iterable<Integer>)stream14::iterator).iterator();
                while (iterator.hasNext()) {
                    integer13 = iterator.next();
                    if (416 == (integer13 & 0xFF) << 4) {
                        integer14 = (integer12 & 0xF);
                        integer15 = (integer12 >> 8 & 0xF);
                        integer16 = (integer12 >> 4 & 0xF);
                        map21 = Maps.newHashMap();
                        map21.put(dynamic3.createString("id"), dynamic3.createString("minecraft:bed"));
                        map21.put(dynamic3.createString("x"), dynamic3.createInt(integer14 + (integer8 << 4)));
                        map21.put(dynamic3.createString("y"), dynamic3.createInt(integer15 + (integer11 << 4)));
                        map21.put(dynamic3.createString("z"), dynamic3.createInt(integer16 + (integer9 << 4)));
                        map21.put(dynamic3.createString("color"), dynamic3.createShort((short)14));
                        list9.add(((Pair)type3.read(dynamic3.createMap((Map)map21)).result().orElseThrow(() -> new IllegalStateException("Could not parse newly created bed block entity."))).getFirst());
                    }
                    ++integer12;
                }
            }
            if (!list9.isEmpty()) {
                return typed.set(opticFinder7, typed2.set(opticFinder8, list9));
            }
            else {
                return typed;
            }
        }));
    }
}
