package net.minecraft.advancements.critereon;

import net.minecraft.tags.Tag;
import net.minecraft.world.entity.EntityType;
import com.google.gson.JsonNull;
import com.google.gson.JsonArray;
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.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;
    public static final EntityPredicate[] ANY_ARRAY;
    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;
    @Nullable
    private final String team;
    @Nullable
    private final ResourceLocation catType;
    
    private EntityPredicate(final EntityTypePredicate bc, final DistancePredicate at, final LocationPredicate bp, final MobEffectsPredicate bs, final NbtPredicate bt, final EntityFlagsPredicate az, final EntityEquipmentPredicate ay, final PlayerPredicate bx, @Nullable final String string, @Nullable final ResourceLocation sm) {
        this.entityType = bc;
        this.distanceToPlayer = at;
        this.location = bp;
        this.effects = bs;
        this.nbt = bt;
        this.flags = az;
        this.equipment = ay;
        this.player = bx;
        this.team = string;
        this.catType = sm;
    }
    
    public boolean matches(final ServerPlayer xe, @Nullable final Entity akq) {
        return this.matches(xe.getLevel(), xe.position(), akq);
    }
    
    public boolean matches(final ServerLevel xd, @Nullable final Vec3 cvl, @Nullable final Entity akq) {
        if (this == EntityPredicate.ANY) {
            return true;
        }
        if (akq == null) {
            return false;
        }
        if (!this.entityType.matches(akq.getType())) {
            return false;
        }
        if (cvl == null) {
            if (this.distanceToPlayer != DistancePredicate.ANY) {
                return false;
            }
        }
        else if (!this.distanceToPlayer.matches(cvl.x, cvl.y, cvl.z, akq.getX(), akq.getY(), akq.getZ())) {
            return false;
        }
        if (!this.location.matches(xd, akq.getX(), akq.getY(), akq.getZ())) {
            return false;
        }
        if (!this.effects.matches(akq)) {
            return false;
        }
        if (!this.nbt.matches(akq)) {
            return false;
        }
        if (!this.flags.matches(akq)) {
            return false;
        }
        if (!this.equipment.matches(akq)) {
            return false;
        }
        if (!this.player.matches(akq)) {
            return false;
        }
        if (this.team != null) {
            final Team cwn5 = akq.getTeam();
            if (cwn5 == null || !this.team.equals(cwn5.getName())) {
                return false;
            }
        }
        return this.catType == null || (akq instanceof Cat && ((Cat)akq).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 bc3 = EntityTypePredicate.fromJson(jsonObject2.get("type"));
        final DistancePredicate at4 = DistancePredicate.fromJson(jsonObject2.get("distance"));
        final LocationPredicate bp5 = LocationPredicate.fromJson(jsonObject2.get("location"));
        final MobEffectsPredicate bs6 = MobEffectsPredicate.fromJson(jsonObject2.get("effects"));
        final NbtPredicate bt7 = NbtPredicate.fromJson(jsonObject2.get("nbt"));
        final EntityFlagsPredicate az8 = EntityFlagsPredicate.fromJson(jsonObject2.get("flags"));
        final EntityEquipmentPredicate ay9 = EntityEquipmentPredicate.fromJson(jsonObject2.get("equipment"));
        final PlayerPredicate bx10 = PlayerPredicate.fromJson(jsonObject2.get("player"));
        final String string11 = GsonHelper.getAsString(jsonObject2, "team", null);
        final ResourceLocation sm12 = jsonObject2.has("catType") ? new ResourceLocation(GsonHelper.getAsString(jsonObject2, "catType")) : null;
        return new Builder().entityType(bc3).distance(at4).located(bp5).effects(bs6).nbt(bt7).flags(az8).equipment(ay9).player(bx10).team(string11).catType(sm12).build();
    }
    
    public static EntityPredicate[] fromJsonArray(@Nullable final JsonElement jsonElement) {
        if (jsonElement == null || jsonElement.isJsonNull()) {
            return EntityPredicate.ANY_ARRAY;
        }
        final JsonArray jsonArray2 = GsonHelper.convertToJsonArray(jsonElement, "entities");
        final EntityPredicate[] arr3 = new EntityPredicate[jsonArray2.size()];
        for (int integer4 = 0; integer4 < jsonArray2.size(); ++integer4) {
            arr3[integer4] = fromJson(jsonArray2.get(integer4));
        }
        return arr3;
    }
    
    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.addProperty("team", this.team);
        if (this.catType != null) {
            jsonObject2.addProperty("catType", this.catType.toString());
        }
        return jsonObject2;
    }
    
    public static JsonElement serializeArrayToJson(final EntityPredicate[] arr) {
        if (arr == EntityPredicate.ANY_ARRAY) {
            return JsonNull.INSTANCE;
        }
        final JsonArray jsonArray2 = new JsonArray();
        for (final EntityPredicate bb6 : arr) {
            final JsonElement jsonElement7 = bb6.serializeToJson();
            if (!jsonElement7.isJsonNull()) {
                jsonArray2.add(jsonElement7);
            }
        }
        return jsonArray2;
    }
    
    static {
        ANY = new EntityPredicate(EntityTypePredicate.ANY, DistancePredicate.ANY, LocationPredicate.ANY, MobEffectsPredicate.ANY, NbtPredicate.ANY, EntityFlagsPredicate.ANY, EntityEquipmentPredicate.ANY, PlayerPredicate.ANY, null, null);
        ANY_ARRAY = new EntityPredicate[0];
    }
    
    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 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;
        }
        
        public static Builder entity() {
            return new Builder();
        }
        
        public Builder of(final EntityType<?> aku) {
            this.entityType = EntityTypePredicate.of(aku);
            return this;
        }
        
        public Builder of(final Tag<EntityType<?>> aaz) {
            this.entityType = EntityTypePredicate.of(aaz);
            return this;
        }
        
        public Builder of(final ResourceLocation sm) {
            this.catType = sm;
            return this;
        }
        
        public Builder entityType(final EntityTypePredicate bc) {
            this.entityType = bc;
            return this;
        }
        
        public Builder distance(final DistancePredicate at) {
            this.distanceToPlayer = at;
            return this;
        }
        
        public Builder located(final LocationPredicate bp) {
            this.location = bp;
            return this;
        }
        
        public Builder effects(final MobEffectsPredicate bs) {
            this.effects = bs;
            return this;
        }
        
        public Builder nbt(final NbtPredicate bt) {
            this.nbt = bt;
            return this;
        }
        
        public Builder flags(final EntityFlagsPredicate az) {
            this.flags = az;
            return this;
        }
        
        public Builder equipment(final EntityEquipmentPredicate ay) {
            this.equipment = ay;
            return this;
        }
        
        public Builder player(final PlayerPredicate bx) {
            this.player = bx;
            return this;
        }
        
        public Builder team(@Nullable final String string) {
            this.team = string;
            return this;
        }
        
        public Builder catType(@Nullable final ResourceLocation sm) {
            this.catType = sm;
            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.team, this.catType, null);
        }
    }
}
