package net.minecraft.advancements.critereon;

import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.ItemLike;
import com.google.common.collect.Lists;
import java.util.List;
import com.google.gson.JsonArray;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import net.minecraft.tags.ItemTags;
import com.google.gson.JsonSyntaxException;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation;
import com.google.gson.JsonParseException;
import net.minecraft.util.GsonHelper;
import com.google.gson.JsonElement;
import net.minecraft.world.item.enchantment.Enchantment;
import java.util.Map;
import net.minecraft.world.item.alchemy.PotionUtils;
import net.minecraft.world.item.EnchantedBookItem;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.alchemy.Potion;
import javax.annotation.Nullable;
import net.minecraft.world.item.Item;
import net.minecraft.tags.Tag;

public class ItemPredicate {
    public static final ItemPredicate ANY;
    @Nullable
    private final Tag<Item> tag;
    @Nullable
    private final Item item;
    private final MinMaxBounds.Ints count;
    private final MinMaxBounds.Ints durability;
    private final EnchantmentPredicate[] enchantments;
    private final EnchantmentPredicate[] storedEnchantments;
    @Nullable
    private final Potion potion;
    private final NbtPredicate nbt;
    
    public ItemPredicate() {
        this.tag = null;
        this.item = null;
        this.potion = null;
        this.count = MinMaxBounds.Ints.ANY;
        this.durability = MinMaxBounds.Ints.ANY;
        this.enchantments = EnchantmentPredicate.NONE;
        this.storedEnchantments = EnchantmentPredicate.NONE;
        this.nbt = NbtPredicate.ANY;
    }
    
    public ItemPredicate(@Nullable final Tag<Item> aaz, @Nullable final Item bei, final MinMaxBounds.Ints d3, final MinMaxBounds.Ints d4, final EnchantmentPredicate[] arr5, final EnchantmentPredicate[] arr6, @Nullable final Potion bgd, final NbtPredicate bt) {
        this.tag = aaz;
        this.item = bei;
        this.count = d3;
        this.durability = d4;
        this.enchantments = arr5;
        this.storedEnchantments = arr6;
        this.potion = bgd;
        this.nbt = bt;
    }
    
    public boolean matches(final ItemStack ben) {
        if (this == ItemPredicate.ANY) {
            return true;
        }
        if (this.tag != null && !this.tag.contains(ben.getItem())) {
            return false;
        }
        if (this.item != null && ben.getItem() != this.item) {
            return false;
        }
        if (!this.count.matches(ben.getCount())) {
            return false;
        }
        if (!this.durability.isAny() && !ben.isDamageableItem()) {
            return false;
        }
        if (!this.durability.matches(ben.getMaxDamage() - ben.getDamageValue())) {
            return false;
        }
        if (!this.nbt.matches(ben)) {
            return false;
        }
        if (this.enchantments.length > 0) {
            final Map<Enchantment, Integer> map3 = EnchantmentHelper.deserializeEnchantments(ben.getEnchantmentTags());
            for (final EnchantmentPredicate aw7 : this.enchantments) {
                if (!aw7.containedIn(map3)) {
                    return false;
                }
            }
        }
        if (this.storedEnchantments.length > 0) {
            final Map<Enchantment, Integer> map3 = EnchantmentHelper.deserializeEnchantments(EnchantedBookItem.getEnchantments(ben));
            for (final EnchantmentPredicate aw7 : this.storedEnchantments) {
                if (!aw7.containedIn(map3)) {
                    return false;
                }
            }
        }
        final Potion bgd3 = PotionUtils.getPotion(ben);
        return this.potion == null || this.potion == bgd3;
    }
    
    public static ItemPredicate fromJson(@Nullable final JsonElement jsonElement) {
        if (jsonElement == null || jsonElement.isJsonNull()) {
            return ItemPredicate.ANY;
        }
        final JsonObject jsonObject2 = GsonHelper.convertToJsonObject(jsonElement, "item");
        final MinMaxBounds.Ints d3 = MinMaxBounds.Ints.fromJson(jsonObject2.get("count"));
        final MinMaxBounds.Ints d4 = MinMaxBounds.Ints.fromJson(jsonObject2.get("durability"));
        if (jsonObject2.has("data")) {
            throw new JsonParseException("Disallowed data tag found");
        }
        final NbtPredicate bt5 = NbtPredicate.fromJson(jsonObject2.get("nbt"));
        Item bei6 = null;
        if (jsonObject2.has("item")) {
            final ResourceLocation sm7 = new ResourceLocation(GsonHelper.getAsString(jsonObject2, "item"));
            final Object o;
            final Object obj;
            bei6 = Registry.ITEM.getOptional(sm7).<Throwable>orElseThrow(() -> {
                new JsonSyntaxException("Unknown item id '" + obj + "'");
                return o;
            });
        }
        Tag<Item> aaz7 = null;
        if (jsonObject2.has("tag")) {
            final ResourceLocation sm8 = new ResourceLocation(GsonHelper.getAsString(jsonObject2, "tag"));
            aaz7 = ItemTags.getAllTags().getTag(sm8);
            if (aaz7 == null) {
                throw new JsonSyntaxException("Unknown item tag '" + sm8 + "'");
            }
        }
        Potion bgd8 = null;
        if (jsonObject2.has("potion")) {
            final ResourceLocation sm9 = new ResourceLocation(GsonHelper.getAsString(jsonObject2, "potion"));
            final Object o2;
            final Object obj2;
            bgd8 = Registry.POTION.getOptional(sm9).<Throwable>orElseThrow(() -> {
                new JsonSyntaxException("Unknown potion '" + obj2 + "'");
                return o2;
            });
        }
        final EnchantmentPredicate[] arr9 = EnchantmentPredicate.fromJsonArray(jsonObject2.get("enchantments"));
        final EnchantmentPredicate[] arr10 = EnchantmentPredicate.fromJsonArray(jsonObject2.get("stored_enchantments"));
        return new ItemPredicate(aaz7, bei6, d3, d4, arr9, arr10, bgd8, bt5);
    }
    
    public JsonElement serializeToJson() {
        if (this == ItemPredicate.ANY) {
            return JsonNull.INSTANCE;
        }
        final JsonObject jsonObject2 = new JsonObject();
        if (this.item != null) {
            jsonObject2.addProperty("item", Registry.ITEM.getKey(this.item).toString());
        }
        if (this.tag != null) {
            jsonObject2.addProperty("tag", this.tag.getId().toString());
        }
        jsonObject2.add("count", this.count.serializeToJson());
        jsonObject2.add("durability", this.durability.serializeToJson());
        jsonObject2.add("nbt", this.nbt.serializeToJson());
        if (this.enchantments.length > 0) {
            final JsonArray jsonArray3 = new JsonArray();
            for (final EnchantmentPredicate aw7 : this.enchantments) {
                jsonArray3.add(aw7.serializeToJson());
            }
            jsonObject2.add("enchantments", jsonArray3);
        }
        if (this.storedEnchantments.length > 0) {
            final JsonArray jsonArray3 = new JsonArray();
            for (final EnchantmentPredicate aw7 : this.storedEnchantments) {
                jsonArray3.add(aw7.serializeToJson());
            }
            jsonObject2.add("stored_enchantments", jsonArray3);
        }
        if (this.potion != null) {
            jsonObject2.addProperty("potion", Registry.POTION.getKey(this.potion).toString());
        }
        return jsonObject2;
    }
    
    public static ItemPredicate[] fromJsonArray(@Nullable final JsonElement jsonElement) {
        if (jsonElement == null || jsonElement.isJsonNull()) {
            return new ItemPredicate[0];
        }
        final JsonArray jsonArray2 = GsonHelper.convertToJsonArray(jsonElement, "items");
        final ItemPredicate[] arr3 = new ItemPredicate[jsonArray2.size()];
        for (int integer4 = 0; integer4 < arr3.length; ++integer4) {
            arr3[integer4] = fromJson(jsonArray2.get(integer4));
        }
        return arr3;
    }
    
    static {
        ANY = new ItemPredicate();
    }
    
    public static class Builder {
        private final List<EnchantmentPredicate> enchantments;
        private final List<EnchantmentPredicate> storedEnchantments;
        @Nullable
        private Item item;
        @Nullable
        private Tag<Item> tag;
        private MinMaxBounds.Ints count;
        private MinMaxBounds.Ints durability;
        @Nullable
        private Potion potion;
        private NbtPredicate nbt;
        
        private Builder() {
            this.enchantments = Lists.newArrayList();
            this.storedEnchantments = Lists.newArrayList();
            this.count = MinMaxBounds.Ints.ANY;
            this.durability = MinMaxBounds.Ints.ANY;
            this.nbt = NbtPredicate.ANY;
        }
        
        public static Builder item() {
            return new Builder();
        }
        
        public Builder of(final ItemLike bjv) {
            this.item = bjv.asItem();
            return this;
        }
        
        public Builder of(final Tag<Item> aaz) {
            this.tag = aaz;
            return this;
        }
        
        public Builder hasNbt(final CompoundTag jt) {
            this.nbt = new NbtPredicate(jt);
            return this;
        }
        
        public Builder hasEnchantment(final EnchantmentPredicate aw) {
            this.enchantments.add(aw);
            return this;
        }
        
        public ItemPredicate build() {
            return new ItemPredicate(this.tag, this.item, this.count, this.durability, this.enchantments.<EnchantmentPredicate>toArray(EnchantmentPredicate.NONE), this.storedEnchantments.<EnchantmentPredicate>toArray(EnchantmentPredicate.NONE), this.potion, this.nbt);
        }
    }
}
