package net.minecraft.util.datafix.fixes;

import java.util.Optional;
import com.google.common.collect.Lists;
import com.mojang.datafixers.Typed;
import com.mojang.datafixers.util.Unit;
import com.mojang.serialization.Dynamic;
import java.util.List;
import com.mojang.datafixers.util.Either;
import com.mojang.datafixers.util.Pair;
import com.mojang.datafixers.OpticFinder;
import com.mojang.datafixers.DSL;
import com.mojang.datafixers.types.Type;
import com.mojang.datafixers.TypeRewriteRule;
import com.mojang.datafixers.schemas.Schema;
import com.mojang.datafixers.DataFix;

public class FurnaceRecipeFix extends DataFix {
    public FurnaceRecipeFix(final Schema schema, final boolean boolean2) {
        super(schema, boolean2);
    }
    
    protected TypeRewriteRule makeRule() {
        return this.cap((com.mojang.datafixers.types.Type<Object>)this.getOutputSchema().getTypeRaw(References.RECIPE));
    }
    
    private <R> TypeRewriteRule cap(final Type<R> type) {
        final Type<Pair<Either<Pair<List<Pair<R, Integer>>, Dynamic<?>>, Unit>, Dynamic<?>>> type2 = (Type<Pair<Either<Pair<List<Pair<R, Integer>>, Dynamic<?>>, Unit>, Dynamic<?>>>)DSL.and(DSL.optional((Type)DSL.field("RecipesUsed", DSL.and((Type)DSL.compoundList((Type)type, DSL.intType()), DSL.remainderType()))), DSL.remainderType());
        final OpticFinder<?> opticFinder4 = DSL.namedChoice("minecraft:furnace", this.getInputSchema().getChoiceType(References.BLOCK_ENTITY, "minecraft:furnace"));
        final OpticFinder<?> opticFinder5 = DSL.namedChoice("minecraft:blast_furnace", this.getInputSchema().getChoiceType(References.BLOCK_ENTITY, "minecraft:blast_furnace"));
        final OpticFinder<?> opticFinder6 = DSL.namedChoice("minecraft:smoker", this.getInputSchema().getChoiceType(References.BLOCK_ENTITY, "minecraft:smoker"));
        final Type<?> type3 = this.getOutputSchema().getChoiceType(References.BLOCK_ENTITY, "minecraft:furnace");
        final Type<?> type4 = this.getOutputSchema().getChoiceType(References.BLOCK_ENTITY, "minecraft:blast_furnace");
        final Type<?> type5 = this.getOutputSchema().getChoiceType(References.BLOCK_ENTITY, "minecraft:smoker");
        final Type<?> type6 = this.getInputSchema().getType(References.BLOCK_ENTITY);
        final Type<?> type7 = this.getOutputSchema().getType(References.BLOCK_ENTITY);
        final OpticFinder opticFinder7;
        final Type type8;
        final com.mojang.datafixers.types.Type<com.mojang.datafixers.util.Pair<com.mojang.datafixers.util.Either<com.mojang.datafixers.util.Pair<List<com.mojang.datafixers.util.Pair<R, Integer>>, Dynamic<?>>, Unit>, Dynamic<?>>> type9;
        return this.fixTypeEverywhereTyped("FurnaceRecipesFix", (Type)type6, (Type)type7, typed -> typed.updateTyped(opticFinder7, type8, typed -> this.<R>updateFurnaceContents(type, type9, typed)).updateTyped((OpticFinder)opticFinder5, (Type)type4, typed -> this.<R>updateFurnaceContents(type, type9, typed)).updateTyped((OpticFinder)opticFinder6, (Type)type5, typed -> this.<R>updateFurnaceContents(type, type9, typed)));
    }
    
    private <R> Typed<?> updateFurnaceContents(final Type<R> type1, final Type<Pair<Either<Pair<List<Pair<R, Integer>>, Dynamic<?>>, Unit>, Dynamic<?>>> type2, final Typed<?> typed) {
        Dynamic<?> dynamic2 = typed.getOrCreate(DSL.remainderFinder());
        final int integer6 = dynamic2.get("RecipesUsedSize").asInt(0);
        dynamic2 = dynamic2.remove("RecipesUsedSize");
        final List<Pair<R, Integer>> list7 = Lists.newArrayList();
        for (int integer7 = 0; integer7 < integer6; ++integer7) {
            final String string9 = "RecipeLocation" + integer7;
            final String string10 = "RecipeAmount" + integer7;
            final Optional<? extends Dynamic<?>> optional11 = dynamic2.get(string9).result();
            final int integer8 = dynamic2.get(string10).asInt(0);
            if (integer8 > 0) {
                final Optional<? extends Pair<Object, ? extends Dynamic<?>>> optional12;
                final List<Pair> list8;
                final int i;
                optional11.ifPresent(dynamic -> {
                    optional12 = type1.read(dynamic).result();
                    optional12.ifPresent(pair -> list8.add(Pair.of(pair.getFirst(), i)));
                    return;
                });
            }
            dynamic2 = dynamic2.remove(string9).remove(string10);
        }
        return typed.set(DSL.remainderFinder(), (Type)type2, Pair.of((Object)Either.left((Object)Pair.of((Object)list7, (Object)dynamic2.emptyMap())), (Object)dynamic2));
    }
}
