package net.minecraft.world.item.crafting;

import org.apache.logging.log4j.LogManager;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonSyntaxException;
import net.minecraft.core.Registry;
import net.minecraft.util.GsonHelper;
import java.util.stream.Stream;
import java.util.Collection;
import java.util.function.Predicate;
import java.util.Objects;
import net.minecraft.world.item.ItemStack;
import net.minecraft.core.NonNullList;
import java.util.Collections;
import java.util.stream.Collectors;
import java.util.Comparator;
import java.util.List;
import net.minecraft.Util;
import java.util.Optional;
import net.minecraft.world.Container;
import net.minecraft.world.level.Level;
import java.util.Iterator;
import java.util.stream.Collector;
import java.util.function.Function;
import com.google.gson.JsonParseException;
import com.google.common.collect.Maps;
import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.server.packs.resources.ResourceManager;
import com.google.gson.JsonObject;
import com.google.common.collect.ImmutableMap;
import net.minecraft.resources.ResourceLocation;
import java.util.Map;
import org.apache.logging.log4j.Logger;
import com.google.gson.Gson;
import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener;

public class RecipeManager extends SimpleJsonResourceReloadListener {
    private static final Gson GSON;
    private static final Logger LOGGER;
    private Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> recipes;
    private boolean hasErrors;
    
    public RecipeManager() {
        super(RecipeManager.GSON, "recipes");
        this.recipes = ImmutableMap.of();
    }
    
    @Override
    protected void apply(final Map<ResourceLocation, JsonObject> map, final ResourceManager zb, final ProfilerFiller aio) {
        this.hasErrors = false;
        final Map<RecipeType<?>, ImmutableMap.Builder<ResourceLocation, Recipe<?>>> map2 = Maps.newHashMap();
        for (final Map.Entry<ResourceLocation, JsonObject> entry2 : map.entrySet()) {
            final ResourceLocation sm8 = entry2.getKey();
            try {
                final Recipe<?> bgw9 = fromJson(sm8, entry2.getValue());
                map2.computeIfAbsent(bgw9.getType(), bgz -> ImmutableMap.builder()).put(sm8, bgw9);
            }
            catch (JsonParseException | IllegalArgumentException ex2) {
                final RuntimeException ex;
                final RuntimeException runtimeException9 = ex;
                RecipeManager.LOGGER.error("Parsing error loading recipe {}", sm8, runtimeException9);
            }
        }
        this.recipes = map2.entrySet().stream().collect(ImmutableMap.toImmutableMap(Map.Entry::getKey, entry -> entry.getValue().build()));
        RecipeManager.LOGGER.info("Loaded {} recipes", map2.size());
    }
    
    public <C extends Container, T extends Recipe<C>> Optional<T> getRecipeFor(final RecipeType<T> bgz, final C aje, final Level bjw) {
        return this.<Container, T>byType(bgz).values().stream().<T>flatMap(bgw -> Util.toStream(bgz.<C>tryMatch(bgw, bjw, aje))).findFirst();
    }
    
    public <C extends Container, T extends Recipe<C>> List<T> getRecipesFor(final RecipeType<T> bgz, final C aje, final Level bjw) {
        return this.<Container, T>byType(bgz).values().stream().flatMap(bgw -> Util.toStream(bgz.<C>tryMatch(bgw, bjw, aje))).sorted(Comparator.comparing(bgw -> bgw.getResultItem().getDescriptionId())).collect(Collectors.toList());
    }
    
    private <C extends Container, T extends Recipe<C>> Map<ResourceLocation, Recipe<C>> byType(final RecipeType<T> bgz) {
        return (Map<ResourceLocation, Recipe<C>>)this.recipes.getOrDefault(bgz, Collections.<ResourceLocation, Recipe<?>>emptyMap());
    }
    
    public <C extends Container, T extends Recipe<C>> NonNullList<ItemStack> getRemainingItemsFor(final RecipeType<T> bgz, final C aje, final Level bjw) {
        final Optional<T> optional5 = this.<C, T>getRecipeFor(bgz, aje, bjw);
        if (optional5.isPresent()) {
            return optional5.get().getRemainingItems(aje);
        }
        final NonNullList<ItemStack> fy6 = NonNullList.<ItemStack>withSize(aje.getContainerSize(), ItemStack.EMPTY);
        for (int integer7 = 0; integer7 < fy6.size(); ++integer7) {
            fy6.set(integer7, aje.getItem(integer7));
        }
        return fy6;
    }
    
    public Optional<? extends Recipe<?>> byKey(final ResourceLocation sm) {
        return this.recipes.values().stream().map(map -> map.get(sm)).filter(Objects::nonNull).findFirst();
    }
    
    public Collection<Recipe<?>> getRecipes() {
        return this.recipes.values().stream().flatMap(map -> map.values().stream()).collect(Collectors.toSet());
    }
    
    public Stream<ResourceLocation> getRecipeIds() {
        return this.recipes.values().stream().<ResourceLocation>flatMap(map -> map.keySet().stream());
    }
    
    public static Recipe<?> fromJson(final ResourceLocation sm, final JsonObject jsonObject) {
        final String string3 = GsonHelper.getAsString(jsonObject, "type");
        final Object o;
        final String str;
        return Registry.RECIPE_SERIALIZER.getOptional(new ResourceLocation(string3)).<Throwable>orElseThrow(() -> {
            new JsonSyntaxException("Invalid or unsupported recipe type '" + str + "'");
            return o;
        }).fromJson(sm, jsonObject);
    }
    
    public void replaceRecipes(final Iterable<Recipe<?>> iterable) {
        // 
        // This method could not be decompiled.
        // 
        // Original Bytecode:
        // 
        //     1: iconst_0       
        //     2: putfield        net/minecraft/world/item/crafting/RecipeManager.hasErrors:Z
        //     5: invokestatic    com/google/common/collect/Maps.newHashMap:()Ljava/util/HashMap;
        //     8: astore_2        /* map3 */
        //     9: aload_1         /* iterable */
        //    10: aload_2         /* map3 */
        //    11: invokedynamic   BootstrapMethod #11, accept:(Ljava/util/Map;)Ljava/util/function/Consumer;
        //    16: invokeinterface java/lang/Iterable.forEach:(Ljava/util/function/Consumer;)V
        //    21: aload_0         /* this */
        //    22: aload_2         /* map3 */
        //    23: invokestatic    com/google/common/collect/ImmutableMap.copyOf:(Ljava/util/Map;)Lcom/google/common/collect/ImmutableMap;
        //    26: putfield        net/minecraft/world/item/crafting/RecipeManager.recipes:Ljava/util/Map;
        //    29: return         
        //    Signature:
        //  (Ljava/lang/Iterable<Lnet/minecraft/world/item/crafting/Recipe<*>;>;)V
        //    MethodParameters:
        //  Name      Flags  
        //  --------  -----
        //  iterable  
        // 
        // The error that occurred was:
        // 
        // java.lang.IllegalStateException: Could not infer any expression.
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:374)
        //     at com.strobel.decompiler.ast.TypeAnalysis.run(TypeAnalysis.java:96)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:344)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:42)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:214)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:99)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethodBody(AstBuilder.java:782)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethod(AstBuilder.java:675)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:552)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:519)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:161)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createType(AstBuilder.java:150)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addType(AstBuilder.java:125)
        //     at cuchaz.enigma.SourceProvider.getSources(SourceProvider.java:85)
        //     at cuchaz.enigma.EnigmaProject$JarExport.decompileClass(EnigmaProject.java:241)
        //     at cuchaz.enigma.EnigmaProject$JarExport.lambda$decompile$1(EnigmaProject.java:230)
        //     at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
        //     at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1654)
        //     at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
        //     at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
        //     at java.base/java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:952)
        //     at java.base/java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:926)
        //     at java.base/java.util.stream.AbstractTask.compute(AbstractTask.java:327)
        //     at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:746)
        //     at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
        //     at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
        //     at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
        //     at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
        //     at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)
        // 
        throw new IllegalStateException("An error occurred while decompiling this method.");
    }
    
    static {
        GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
        LOGGER = LogManager.getLogger();
    }
}
