package net.minecraft.advancements.critereon;

import java.util.Collections;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.GsonHelper;
import javax.annotation.Nullable;
import com.google.gson.JsonElement;
import java.util.Iterator;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Entity;
import com.google.common.collect.Maps;
import net.minecraft.world.effect.MobEffect;
import java.util.Map;

public class MobEffectsPredicate {
    public static final MobEffectsPredicate ANY;
    private final Map<MobEffect, MobEffectInstancePredicate> effects;
    
    public MobEffectsPredicate(final Map<MobEffect, MobEffectInstancePredicate> map) {
        this.effects = map;
    }
    
    public static MobEffectsPredicate effects() {
        return new MobEffectsPredicate(Maps.newHashMap());
    }
    
    public MobEffectsPredicate and(final MobEffect aki) {
        this.effects.put(aki, new MobEffectInstancePredicate());
        return this;
    }
    
    public boolean matches(final Entity akq) {
        return this == MobEffectsPredicate.ANY || (akq instanceof LivingEntity && this.matches(((LivingEntity)akq).getActiveEffectsMap()));
    }
    
    public boolean matches(final LivingEntity akz) {
        return this == MobEffectsPredicate.ANY || this.matches(akz.getActiveEffectsMap());
    }
    
    public boolean matches(final Map<MobEffect, MobEffectInstance> map) {
        if (this == MobEffectsPredicate.ANY) {
            return true;
        }
        for (final Map.Entry<MobEffect, MobEffectInstancePredicate> entry4 : this.effects.entrySet()) {
            final MobEffectInstance akk5 = map.get(entry4.getKey());
            if (!entry4.getValue().matches(akk5)) {
                return false;
            }
        }
        return true;
    }
    
    public static MobEffectsPredicate fromJson(@Nullable final JsonElement jsonElement) {
        if (jsonElement == null || jsonElement.isJsonNull()) {
            return MobEffectsPredicate.ANY;
        }
        final JsonObject jsonObject2 = GsonHelper.convertToJsonObject(jsonElement, "effects");
        final Map<MobEffect, MobEffectInstancePredicate> map3 = Maps.newHashMap();
        for (final Map.Entry<String, JsonElement> entry5 : jsonObject2.entrySet()) {
            final ResourceLocation sm6 = new ResourceLocation(entry5.getKey());
            final Object o;
            final Object obj;
            final MobEffect aki7 = Registry.MOB_EFFECT.getOptional(sm6).<Throwable>orElseThrow(() -> {
                new JsonSyntaxException("Unknown effect '" + obj + "'");
                return o;
            });
            final MobEffectInstancePredicate a8 = MobEffectInstancePredicate.fromJson(GsonHelper.convertToJsonObject(entry5.getValue(), entry5.getKey()));
            map3.put(aki7, a8);
        }
        return new MobEffectsPredicate(map3);
    }
    
    public JsonElement serializeToJson() {
        if (this == MobEffectsPredicate.ANY) {
            return JsonNull.INSTANCE;
        }
        final JsonObject jsonObject2 = new JsonObject();
        for (final Map.Entry<MobEffect, MobEffectInstancePredicate> entry4 : this.effects.entrySet()) {
            jsonObject2.add(Registry.MOB_EFFECT.getKey(entry4.getKey()).toString(), entry4.getValue().serializeToJson());
        }
        return jsonObject2;
    }
    
    static {
        ANY = new MobEffectsPredicate(Collections.<MobEffect, MobEffectInstancePredicate>emptyMap());
    }
    
    public static class MobEffectInstancePredicate {
        private final MinMaxBounds.Ints amplifier;
        private final MinMaxBounds.Ints duration;
        @Nullable
        private final Boolean ambient;
        @Nullable
        private final Boolean visible;
        
        public MobEffectInstancePredicate(final MinMaxBounds.Ints d1, final MinMaxBounds.Ints d2, @Nullable final Boolean boolean3, @Nullable final Boolean boolean4) {
            this.amplifier = d1;
            this.duration = d2;
            this.ambient = boolean3;
            this.visible = boolean4;
        }
        
        public MobEffectInstancePredicate() {
            this(MinMaxBounds.Ints.ANY, MinMaxBounds.Ints.ANY, null, null);
        }
        
        public boolean matches(@Nullable final MobEffectInstance akk) {
            return akk != null && this.amplifier.matches(akk.getAmplifier()) && this.duration.matches(akk.getDuration()) && (this.ambient == null || this.ambient == akk.isAmbient()) && (this.visible == null || this.visible == akk.isVisible());
        }
        
        public JsonElement serializeToJson() {
            final JsonObject jsonObject2 = new JsonObject();
            jsonObject2.add("amplifier", this.amplifier.serializeToJson());
            jsonObject2.add("duration", this.duration.serializeToJson());
            jsonObject2.addProperty("ambient", this.ambient);
            jsonObject2.addProperty("visible", this.visible);
            return jsonObject2;
        }
        
        public static MobEffectInstancePredicate fromJson(final JsonObject jsonObject) {
            final MinMaxBounds.Ints d2 = MinMaxBounds.Ints.fromJson(jsonObject.get("amplifier"));
            final MinMaxBounds.Ints d3 = MinMaxBounds.Ints.fromJson(jsonObject.get("duration"));
            final Boolean boolean4 = jsonObject.has("ambient") ? Boolean.valueOf(GsonHelper.getAsBoolean(jsonObject, "ambient")) : null;
            final Boolean boolean5 = jsonObject.has("visible") ? Boolean.valueOf(GsonHelper.getAsBoolean(jsonObject, "visible")) : null;
            return new MobEffectInstancePredicate(d2, d3, boolean4, boolean5);
        }
    }
}
