package net.minecraft.advancements.critereon;

import com.google.common.collect.UnmodifiableIterator;
import java.util.Collection;
import com.google.common.collect.ImmutableSet;
import java.util.Iterator;
import java.util.List;
import com.google.common.collect.Lists;
import java.util.function.Predicate;
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;
import net.minecraft.advancements.CriterionTriggerInstance;

public abstract class SimpleCriterionTrigger<T extends CriterionTriggerInstance> implements CriterionTrigger<T> {
    private final Map<PlayerAdvancements, Set<Listener<T>>> players;
    
    public SimpleCriterionTrigger() {
        this.players = Maps.newIdentityHashMap();
    }
    
    @Override
    public final void addPlayerListener(final PlayerAdvancements sv, final Listener<T> a) {
        this.players.computeIfAbsent(sv, sv -> Sets.newHashSet()).add(a);
    }
    
    @Override
    public final void removePlayerListener(final PlayerAdvancements sv, final Listener<T> a) {
        final Set<Listener<T>> set4 = this.players.get(sv);
        if (set4 != null) {
            set4.remove(a);
            if (set4.isEmpty()) {
                this.players.remove(sv);
            }
        }
    }
    
    @Override
    public final void removePlayerListeners(final PlayerAdvancements sv) {
        this.players.remove(sv);
    }
    
    protected void trigger(final PlayerAdvancements sv, final Predicate<T> predicate) {
        final Set<Listener<T>> set4 = this.players.get(sv);
        if (set4 == null) {
            return;
        }
        List<Listener<T>> list5 = null;
        for (final Listener<T> a7 : set4) {
            if (predicate.test(a7.getTriggerInstance())) {
                if (list5 == null) {
                    list5 = Lists.newArrayList();
                }
                list5.add(a7);
            }
        }
        if (list5 != null) {
            for (final Listener<T> a7 : list5) {
                a7.run(sv);
            }
        }
    }
    
    protected void trigger(final PlayerAdvancements sv) {
        final Set<Listener<T>> set3 = this.players.get(sv);
        if (set3 != null && !set3.isEmpty()) {
            for (final Listener<T> a5 : ImmutableSet.<Listener<T>>copyOf(set3)) {
                a5.run(sv);
            }
        }
    }
}
