package net.minecraft.advancements.critereon;

import net.minecraft.advancements.CriterionTriggerInstance;
import java.util.Iterator;
import java.util.List;
import net.minecraft.world.level.storage.loot.LootContext;
import com.google.common.collect.Lists;
import net.minecraft.world.entity.Entity;
import java.util.function.Predicate;
import net.minecraft.server.level.ServerPlayer;
import com.google.gson.JsonObject;
import com.google.common.collect.Sets;
import com.google.common.collect.Maps;
import java.util.Set;
import net.minecraft.server.PlayerAdvancements;
import java.util.Map;
import net.minecraft.advancements.CriterionTrigger;

public abstract class SimpleCriterionTrigger<T extends AbstractCriterionTriggerInstance> implements CriterionTrigger<T> {
    private final Map<PlayerAdvancements, Set<Listener<T>>> players;
    
    public SimpleCriterionTrigger() {
        this.players = Maps.newIdentityHashMap();
    }
    
    @Override
    public final void addPlayerListener(final PlayerAdvancements uq, final Listener<T> a) {
        this.players.computeIfAbsent(uq, uq -> Sets.newHashSet()).add(a);
    }
    
    @Override
    public final void removePlayerListener(final PlayerAdvancements uq, final Listener<T> a) {
        final Set<Listener<T>> set4 = this.players.get(uq);
        if (set4 != null) {
            set4.remove(a);
            if (set4.isEmpty()) {
                this.players.remove(uq);
            }
        }
    }
    
    @Override
    public final void removePlayerListeners(final PlayerAdvancements uq) {
        this.players.remove(uq);
    }
    
    protected abstract T createInstance(final JsonObject jsonObject, final EntityPredicate.Composite b, final DeserializationContext av);
    
    @Override
    public final T createInstance(final JsonObject jsonObject, final DeserializationContext av) {
        final EntityPredicate.Composite b4 = EntityPredicate.Composite.fromJson(jsonObject, "player", av);
        return this.createInstance(jsonObject, b4, av);
    }
    
    protected void trigger(final ServerPlayer ze, final Predicate<T> predicate) {
        final PlayerAdvancements uq4 = ze.getAdvancements();
        final Set<Listener<T>> set5 = this.players.get(uq4);
        if (set5 == null || set5.isEmpty()) {
            return;
        }
        final LootContext dat6 = EntityPredicate.createContext(ze, ze);
        List<Listener<T>> list7 = null;
        for (final Listener<T> a9 : set5) {
            final T aj10 = a9.getTriggerInstance();
            if (aj10.getPlayerPredicate().matches(dat6) && predicate.test(aj10)) {
                if (list7 == null) {
                    list7 = Lists.newArrayList();
                }
                list7.add(a9);
            }
        }
        if (list7 != null) {
            for (final Listener<T> a9 : list7) {
                a9.run(uq4);
            }
        }
    }
}
