package net.minecraft.advancements.critereon;

import net.minecraft.world.level.storage.loot.predicates.LootItemEntityPropertyCondition;
import com.google.gson.JsonArray;
import net.minecraft.world.level.storage.loot.predicates.LootItemConditions;
import java.util.function.Predicate;
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
import net.minecraft.tags.Tag;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.level.storage.loot.LootContext;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import net.minecraft.util.GsonHelper;
import com.google.gson.JsonElement;
import net.minecraft.world.scores.Team;
import net.minecraft.world.entity.animal.Cat;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.phys.Vec3;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.resources.ResourceLocation;
import javax.annotation.Nullable;

public class EntityPredicate {
    public static final EntityPredicate ANY;
    private final EntityTypePredicate entityType;
    private final DistancePredicate distanceToPlayer;
    private final LocationPredicate location;
    private final MobEffectsPredicate effects;
    private final NbtPredicate nbt;
    private final EntityFlagsPredicate flags;
    private final EntityEquipmentPredicate equipment;
    private final PlayerPredicate player;
    private final FishingHookPredicate fishingHook;
    private final EntityPredicate vehicle;
    private final EntityPredicate targetedEntity;
    @Nullable
    private final String team;
    @Nullable
    private final ResourceLocation catType;
    
    private EntityPredicate(final EntityTypePredicate bf, final DistancePredicate aw, final LocationPredicate bu, final MobEffectsPredicate by, final NbtPredicate bz, final EntityFlagsPredicate bc, final EntityEquipmentPredicate bb, final PlayerPredicate ce, final FishingHookPredicate bh, @Nullable final String string, @Nullable final ResourceLocation uh) {
        this.entityType = bf;
        this.distanceToPlayer = aw;
        this.location = bu;
        this.effects = by;
        this.nbt = bz;
        this.flags = bc;
        this.equipment = bb;
        this.player = ce;
        this.fishingHook = bh;
        this.vehicle = this;
        this.targetedEntity = this;
        this.team = string;
        this.catType = uh;
    }
    
    private EntityPredicate(final EntityTypePredicate bf, final DistancePredicate aw, final LocationPredicate bu, final MobEffectsPredicate by, final NbtPredicate bz, final EntityFlagsPredicate bc, final EntityEquipmentPredicate bb, final PlayerPredicate ce, final FishingHookPredicate bh, final EntityPredicate be10, final EntityPredicate be11, @Nullable final String string, @Nullable final ResourceLocation uh) {
        this.entityType = bf;
        this.distanceToPlayer = aw;
        this.location = bu;
        this.effects = by;
        this.nbt = bz;
        this.flags = bc;
        this.equipment = bb;
        this.player = ce;
        this.fishingHook = bh;
        this.vehicle = be10;
        this.targetedEntity = be11;
        this.team = string;
        this.catType = uh;
    }
    
    public boolean matches(final ServerPlayer ze, @Nullable final Entity aom) {
        return this.matches(ze.getLevel(), ze.position(), aom);
    }
    
    public boolean matches(final ServerLevel zd, @Nullable final Vec3 dem, @Nullable final Entity aom) {
        if (this == EntityPredicate.ANY) {
            return true;
        }
        if (aom == null) {
            return false;
        }
        if (!this.entityType.matches(aom.getType())) {
            return false;
        }
        if (dem == null) {
            if (this.distanceToPlayer != DistancePredicate.ANY) {
                return false;
            }
        }
        else if (!this.distanceToPlayer.matches(dem.x, dem.y, dem.z, aom.getX(), aom.getY(), aom.getZ())) {
            return false;
        }
        if (!this.location.matches(zd, aom.getX(), aom.getY(), aom.getZ())) {
            return false;
        }
        if (!this.effects.matches(aom)) {
            return false;
        }
        if (!this.nbt.matches(aom)) {
            return false;
        }
        if (!this.flags.matches(aom)) {
            return false;
        }
        if (!this.equipment.matches(aom)) {
            return false;
        }
        if (!this.player.matches(aom)) {
            return false;
        }
        if (!this.fishingHook.matches(aom)) {
            return false;
        }
        if (!this.vehicle.matches(zd, dem, aom.getVehicle())) {
            return false;
        }
        if (!this.targetedEntity.matches(zd, dem, (aom instanceof Mob) ? ((Mob)aom).getTarget() : null)) {
            return false;
        }
        if (this.team != null) {
            final Team dfo5 = aom.getTeam();
            if (dfo5 == null || !this.team.equals(dfo5.getName())) {
                return false;
            }
        }
        return this.catType == null || (aom instanceof Cat && ((Cat)aom).getResourceLocation().equals(this.catType));
    }
    
    public static EntityPredicate fromJson(@Nullable final JsonElement jsonElement) {
        if (jsonElement == null || jsonElement.isJsonNull()) {
            return EntityPredicate.ANY;
        }
        final JsonObject jsonObject2 = GsonHelper.convertToJsonObject(jsonElement, "entity");
        final EntityTypePredicate bf3 = EntityTypePredicate.fromJson(jsonObject2.get("type"));
        final DistancePredicate aw4 = DistancePredicate.fromJson(jsonObject2.get("distance"));
        final LocationPredicate bu5 = LocationPredicate.fromJson(jsonObject2.get("location"));
        final MobEffectsPredicate by6 = MobEffectsPredicate.fromJson(jsonObject2.get("effects"));
        final NbtPredicate bz7 = NbtPredicate.fromJson(jsonObject2.get("nbt"));
        final EntityFlagsPredicate bc8 = EntityFlagsPredicate.fromJson(jsonObject2.get("flags"));
        final EntityEquipmentPredicate bb9 = EntityEquipmentPredicate.fromJson(jsonObject2.get("equipment"));
        final PlayerPredicate ce10 = PlayerPredicate.fromJson(jsonObject2.get("player"));
        final FishingHookPredicate bh11 = FishingHookPredicate.fromJson(jsonObject2.get("fishing_hook"));
        final EntityPredicate be12 = fromJson(jsonObject2.get("vehicle"));
        final EntityPredicate be13 = fromJson(jsonObject2.get("targeted_entity"));
        final String string14 = GsonHelper.getAsString(jsonObject2, "team", null);
        final ResourceLocation uh15 = jsonObject2.has("catType") ? new ResourceLocation(GsonHelper.getAsString(jsonObject2, "catType")) : null;
        return new Builder().entityType(bf3).distance(aw4).located(bu5).effects(by6).nbt(bz7).flags(bc8).equipment(bb9).player(ce10).fishingHook(bh11).team(string14).vehicle(be12).targetedEntity(be13).catType(uh15).build();
    }
    
    public JsonElement serializeToJson() {
        if (this == EntityPredicate.ANY) {
            return JsonNull.INSTANCE;
        }
        final JsonObject jsonObject2 = new JsonObject();
        jsonObject2.add("type", this.entityType.serializeToJson());
        jsonObject2.add("distance", this.distanceToPlayer.serializeToJson());
        jsonObject2.add("location", this.location.serializeToJson());
        jsonObject2.add("effects", this.effects.serializeToJson());
        jsonObject2.add("nbt", this.nbt.serializeToJson());
        jsonObject2.add("flags", this.flags.serializeToJson());
        jsonObject2.add("equipment", this.equipment.serializeToJson());
        jsonObject2.add("player", this.player.serializeToJson());
        jsonObject2.add("fishing_hook", this.fishingHook.serializeToJson());
        jsonObject2.add("vehicle", this.vehicle.serializeToJson());
        jsonObject2.add("targeted_entity", this.targetedEntity.serializeToJson());
        jsonObject2.addProperty("team", this.team);
        if (this.catType != null) {
            jsonObject2.addProperty("catType", this.catType.toString());
        }
        return jsonObject2;
    }
    
    public static LootContext createContext(final ServerPlayer ze, final Entity aom) {
        return new LootContext.Builder(ze.getLevel()).<Entity>withParameter(LootContextParams.THIS_ENTITY, aom).<BlockPos>withParameter(LootContextParams.BLOCK_POS, aom.blockPosition()).<Vec3>withParameter(LootContextParams.ORIGIN, ze.position()).withRandom(ze.getRandom()).create(LootContextParamSets.ADVANCEMENT_ENTITY);
    }
    
    static {
        ANY = new EntityPredicate(EntityTypePredicate.ANY, DistancePredicate.ANY, LocationPredicate.ANY, MobEffectsPredicate.ANY, NbtPredicate.ANY, EntityFlagsPredicate.ANY, EntityEquipmentPredicate.ANY, PlayerPredicate.ANY, FishingHookPredicate.ANY, null, null);
    }
    
    public static class Builder {
        private EntityTypePredicate entityType;
        private DistancePredicate distanceToPlayer;
        private LocationPredicate location;
        private MobEffectsPredicate effects;
        private NbtPredicate nbt;
        private EntityFlagsPredicate flags;
        private EntityEquipmentPredicate equipment;
        private PlayerPredicate player;
        private FishingHookPredicate fishingHook;
        private EntityPredicate vehicle;
        private EntityPredicate targetedEntity;
        private String team;
        private ResourceLocation catType;
        
        public Builder() {
            this.entityType = EntityTypePredicate.ANY;
            this.distanceToPlayer = DistancePredicate.ANY;
            this.location = LocationPredicate.ANY;
            this.effects = MobEffectsPredicate.ANY;
            this.nbt = NbtPredicate.ANY;
            this.flags = EntityFlagsPredicate.ANY;
            this.equipment = EntityEquipmentPredicate.ANY;
            this.player = PlayerPredicate.ANY;
            this.fishingHook = FishingHookPredicate.ANY;
            this.vehicle = EntityPredicate.ANY;
            this.targetedEntity = EntityPredicate.ANY;
        }
        
        public static Builder entity() {
            return new Builder();
        }
        
        public Builder of(final EntityType<?> aoq) {
            this.entityType = EntityTypePredicate.of(aoq);
            return this;
        }
        
        public Builder of(final Tag<EntityType<?>> adf) {
            this.entityType = EntityTypePredicate.of(adf);
            return this;
        }
        
        public Builder of(final ResourceLocation uh) {
            this.catType = uh;
            return this;
        }
        
        public Builder entityType(final EntityTypePredicate bf) {
            this.entityType = bf;
            return this;
        }
        
        public Builder distance(final DistancePredicate aw) {
            this.distanceToPlayer = aw;
            return this;
        }
        
        public Builder located(final LocationPredicate bu) {
            this.location = bu;
            return this;
        }
        
        public Builder effects(final MobEffectsPredicate by) {
            this.effects = by;
            return this;
        }
        
        public Builder nbt(final NbtPredicate bz) {
            this.nbt = bz;
            return this;
        }
        
        public Builder flags(final EntityFlagsPredicate bc) {
            this.flags = bc;
            return this;
        }
        
        public Builder equipment(final EntityEquipmentPredicate bb) {
            this.equipment = bb;
            return this;
        }
        
        public Builder player(final PlayerPredicate ce) {
            this.player = ce;
            return this;
        }
        
        public Builder fishingHook(final FishingHookPredicate bh) {
            this.fishingHook = bh;
            return this;
        }
        
        public Builder vehicle(final EntityPredicate be) {
            this.vehicle = be;
            return this;
        }
        
        public Builder targetedEntity(final EntityPredicate be) {
            this.targetedEntity = be;
            return this;
        }
        
        public Builder team(@Nullable final String string) {
            this.team = string;
            return this;
        }
        
        public Builder catType(@Nullable final ResourceLocation uh) {
            this.catType = uh;
            return this;
        }
        
        public EntityPredicate build() {
            return new EntityPredicate(this.entityType, this.distanceToPlayer, this.location, this.effects, this.nbt, this.flags, this.equipment, this.player, this.fishingHook, this.vehicle, this.targetedEntity, this.team, this.catType, null);
        }
    }
    
    public static class Composite {
        public static final Composite ANY;
        private final LootItemCondition[] conditions;
        private final Predicate<LootContext> compositePredicates;
        
        private Composite(final LootItemCondition[] arr) {
            this.conditions = arr;
            this.compositePredicates = LootItemConditions.<LootContext>andConditions(arr);
        }
        
        public static Composite create(final LootItemCondition... arr) {
            return new Composite(arr);
        }
        
        public static Composite fromJson(final JsonObject jsonObject, final String string, final DeserializationContext av) {
            final JsonElement jsonElement4 = jsonObject.get(string);
            return fromElement(string, av, jsonElement4);
        }
        
        public static Composite[] fromJsonArray(final JsonObject jsonObject, final String string, final DeserializationContext av) {
            final JsonElement jsonElement4 = jsonObject.get(string);
            if (jsonElement4 == null || jsonElement4.isJsonNull()) {
                return new Composite[0];
            }
            final JsonArray jsonArray5 = GsonHelper.convertToJsonArray(jsonElement4, string);
            final Composite[] arr6 = new Composite[jsonArray5.size()];
            for (int integer7 = 0; integer7 < jsonArray5.size(); ++integer7) {
                arr6[integer7] = fromElement(string + "[" + integer7 + "]", av, jsonArray5.get(integer7));
            }
            return arr6;
        }
        
        private static Composite fromElement(final String string, final DeserializationContext av, @Nullable final JsonElement jsonElement) {
            if (jsonElement != null && jsonElement.isJsonArray()) {
                final LootItemCondition[] arr4 = av.deserializeConditions(jsonElement.getAsJsonArray(), av.getAdvancementId().toString() + "/" + string, LootContextParamSets.ADVANCEMENT_ENTITY);
                return new Composite(arr4);
            }
            final EntityPredicate be4 = EntityPredicate.fromJson(jsonElement);
            return wrap(be4);
        }
        
        public static Composite wrap(final EntityPredicate be) {
            if (be == EntityPredicate.ANY) {
                return Composite.ANY;
            }
            final LootItemCondition ddm2 = LootItemEntityPropertyCondition.hasProperties(LootContext.EntityTarget.THIS, be).build();
            return new Composite(new LootItemCondition[] { ddm2 });
        }
        
        public boolean matches(final LootContext dat) {
            return this.compositePredicates.test(dat);
        }
        
        public JsonElement toJson(final SerializationContext cg) {
            if (this.conditions.length == 0) {
                return JsonNull.INSTANCE;
            }
            return cg.serializeConditions(this.conditions);
        }
        
        public static JsonElement toJson(final Composite[] arr, final SerializationContext cg) {
            if (arr.length == 0) {
                return JsonNull.INSTANCE;
            }
            final JsonArray jsonArray3 = new JsonArray();
            for (final Composite b7 : arr) {
                jsonArray3.add(b7.toJson(cg));
            }
            return jsonArray3;
        }
        
        static {
            ANY = new Composite(new LootItemCondition[0]);
        }
    }
}
