package net.minecraft.stats;

import java.util.AbstractList;
import org.apache.logging.log4j.LogManager;
import java.util.Optional;
import net.minecraft.ResourceLocationException;
import java.util.function.Consumer;
import net.minecraft.nbt.Tag;
import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.Packet;
import java.util.Collections;
import java.util.Iterator;
import net.minecraft.resources.ResourceLocation;
import java.util.List;
import net.minecraft.network.protocol.game.ClientboundRecipePacket;
import net.minecraft.advancements.CriteriaTriggers;
import com.google.common.collect.Lists;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.crafting.Recipe;
import java.util.Collection;
import net.minecraft.world.item.crafting.RecipeManager;
import org.apache.logging.log4j.Logger;

public class ServerRecipeBook extends RecipeBook {
    private static final Logger LOGGER;
    private final RecipeManager manager;
    
    public ServerRecipeBook(final RecipeManager bgx) {
        this.manager = bgx;
    }
    
    public int addRecipes(final Collection<Recipe<?>> collection, final ServerPlayer xe) {
        final List<ResourceLocation> list4 = Lists.newArrayList();
        int integer5 = 0;
        for (final Recipe<?> bgw7 : collection) {
            final ResourceLocation sm8 = bgw7.getId();
            if (!this.known.contains(sm8) && !bgw7.isSpecial()) {
                this.add(sm8);
                this.addHighlight(sm8);
                list4.add(sm8);
                CriteriaTriggers.RECIPE_UNLOCKED.trigger(xe, bgw7);
                ++integer5;
            }
        }
        this.sendRecipes(ClientboundRecipePacket.State.ADD, xe, list4);
        return integer5;
    }
    
    public int removeRecipes(final Collection<Recipe<?>> collection, final ServerPlayer xe) {
        final List<ResourceLocation> list4 = Lists.newArrayList();
        int integer5 = 0;
        for (final Recipe<?> bgw7 : collection) {
            final ResourceLocation sm8 = bgw7.getId();
            if (this.known.contains(sm8)) {
                this.remove(sm8);
                list4.add(sm8);
                ++integer5;
            }
        }
        this.sendRecipes(ClientboundRecipePacket.State.REMOVE, xe, list4);
        return integer5;
    }
    
    private void sendRecipes(final ClientboundRecipePacket.State a, final ServerPlayer xe, final List<ResourceLocation> list) {
        xe.connection.send(new ClientboundRecipePacket(a, list, Collections.emptyList(), this.guiOpen, this.filteringCraftable, this.furnaceGuiOpen, this.furnaceFilteringCraftable));
    }
    
    public CompoundTag toNbt() {
        final CompoundTag jt2 = new CompoundTag();
        jt2.putBoolean("isGuiOpen", this.guiOpen);
        jt2.putBoolean("isFilteringCraftable", this.filteringCraftable);
        jt2.putBoolean("isFurnaceGuiOpen", this.furnaceGuiOpen);
        jt2.putBoolean("isFurnaceFilteringCraftable", this.furnaceFilteringCraftable);
        final ListTag jz3 = new ListTag();
        for (final ResourceLocation sm5 : this.known) {
            ((AbstractList<StringTag>)jz3).add(StringTag.valueOf(sm5.toString()));
        }
        jt2.put("recipes", jz3);
        final ListTag jz4 = new ListTag();
        for (final ResourceLocation sm6 : this.highlight) {
            ((AbstractList<StringTag>)jz4).add(StringTag.valueOf(sm6.toString()));
        }
        jt2.put("toBeDisplayed", jz4);
        return jt2;
    }
    
    public void fromNbt(final CompoundTag jt) {
        this.guiOpen = jt.getBoolean("isGuiOpen");
        this.filteringCraftable = jt.getBoolean("isFilteringCraftable");
        this.furnaceGuiOpen = jt.getBoolean("isFurnaceGuiOpen");
        this.furnaceFilteringCraftable = jt.getBoolean("isFurnaceFilteringCraftable");
        final ListTag jz3 = jt.getList("recipes", 8);
        this.loadRecipes(jz3, this::add);
        final ListTag jz4 = jt.getList("toBeDisplayed", 8);
        this.loadRecipes(jz4, this::addHighlight);
    }
    
    private void loadRecipes(final ListTag jz, final Consumer<Recipe<?>> consumer) {
        for (int integer4 = 0; integer4 < jz.size(); ++integer4) {
            final String string5 = jz.getString(integer4);
            try {
                final ResourceLocation sm6 = new ResourceLocation(string5);
                final Optional<? extends Recipe<?>> optional7 = this.manager.byKey(sm6);
                if (!optional7.isPresent()) {
                    ServerRecipeBook.LOGGER.error("Tried to load unrecognized recipe: {} removed now.", sm6);
                }
                else {
                    consumer.accept(optional7.get());
                }
            }
            catch (ResourceLocationException r6) {
                ServerRecipeBook.LOGGER.error("Tried to load improperly formatted recipe: {} removed now.", string5);
            }
        }
    }
    
    public void sendInitialRecipeBook(final ServerPlayer xe) {
        xe.connection.send(new ClientboundRecipePacket(ClientboundRecipePacket.State.INIT, this.known, this.highlight, this.guiOpen, this.filteringCraftable, this.furnaceGuiOpen, this.furnaceFilteringCraftable));
    }
    
    static {
        LOGGER = LogManager.getLogger();
    }
}
