package net.minecraft.advancements;

import org.apache.logging.log4j.LogManager;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.function.Function;
import com.google.common.base.Functions;
import java.util.Iterator;
import com.google.common.collect.Sets;
import com.google.common.collect.Maps;
import java.util.Set;
import net.minecraft.resources.ResourceLocation;
import java.util.Map;
import org.apache.logging.log4j.Logger;

public class AdvancementList {
    private static final Logger LOGGER;
    private final Map<ResourceLocation, Advancement> advancements;
    private final Set<Advancement> roots;
    private final Set<Advancement> tasks;
    private Listener listener;
    
    public AdvancementList() {
        this.advancements = Maps.newHashMap();
        this.roots = Sets.newLinkedHashSet();
        this.tasks = Sets.newLinkedHashSet();
    }
    
    private void remove(final Advancement w) {
        for (final Advancement w2 : w.getChildren()) {
            this.remove(w2);
        }
        AdvancementList.LOGGER.info("Forgot about advancement {}", w.getId());
        this.advancements.remove(w.getId());
        if (w.getParent() == null) {
            this.roots.remove(w);
            if (this.listener != null) {
                this.listener.onRemoveAdvancementRoot(w);
            }
        }
        else {
            this.tasks.remove(w);
            if (this.listener != null) {
                this.listener.onRemoveAdvancementTask(w);
            }
        }
    }
    
    public void remove(final Set<ResourceLocation> set) {
        for (final ResourceLocation uh4 : set) {
            final Advancement w5 = this.advancements.get(uh4);
            if (w5 == null) {
                AdvancementList.LOGGER.warn("Told to remove advancement {} but I don't know what that is", uh4);
            }
            else {
                this.remove(w5);
            }
        }
    }
    
    public void add(final Map<ResourceLocation, Advancement.Builder> map) {
        final Function<ResourceLocation, Advancement> function3 = Functions.forMap(this.advancements, null);
        while (!map.isEmpty()) {
            boolean boolean4 = false;
            final Iterator<Map.Entry<ResourceLocation, Advancement.Builder>> iterator5 = map.entrySet().iterator();
            while (iterator5.hasNext()) {
                final Map.Entry<ResourceLocation, Advancement.Builder> entry6 = iterator5.next();
                final ResourceLocation uh7 = entry6.getKey();
                final Advancement.Builder a8 = entry6.getValue();
                if (a8.canBuild(function3)) {
                    final Advancement w9 = a8.build(uh7);
                    this.advancements.put(uh7, w9);
                    boolean4 = true;
                    iterator5.remove();
                    if (w9.getParent() == null) {
                        this.roots.add(w9);
                        if (this.listener == null) {
                            continue;
                        }
                        this.listener.onAddAdvancementRoot(w9);
                    }
                    else {
                        this.tasks.add(w9);
                        if (this.listener == null) {
                            continue;
                        }
                        this.listener.onAddAdvancementTask(w9);
                    }
                }
            }
            if (!boolean4) {
                for (final Map.Entry<ResourceLocation, Advancement.Builder> entry6 : map.entrySet()) {
                    AdvancementList.LOGGER.error("Couldn't load advancement {}: {}", entry6.getKey(), entry6.getValue());
                }
                break;
            }
        }
        AdvancementList.LOGGER.info("Loaded {} advancements", this.advancements.size());
    }
    
    public void clear() {
        this.advancements.clear();
        this.roots.clear();
        this.tasks.clear();
        if (this.listener != null) {
            this.listener.onAdvancementsCleared();
        }
    }
    
    public Iterable<Advancement> getRoots() {
        return this.roots;
    }
    
    public Collection<Advancement> getAllAdvancements() {
        return this.advancements.values();
    }
    
    @Nullable
    public Advancement get(final ResourceLocation uh) {
        return this.advancements.get(uh);
    }
    
    public void setListener(@Nullable final Listener a) {
        this.listener = a;
        if (a != null) {
            for (final Advancement w4 : this.roots) {
                a.onAddAdvancementRoot(w4);
            }
            for (final Advancement w4 : this.tasks) {
                a.onAddAdvancementTask(w4);
            }
        }
    }
    
    static {
        LOGGER = LogManager.getLogger();
    }
    
    public interface Listener {
        void onAddAdvancementRoot(final Advancement w);
        
        void onRemoveAdvancementRoot(final Advancement w);
        
        void onAddAdvancementTask(final Advancement w);
        
        void onRemoveAdvancementTask(final Advancement w);
        
        void onAdvancementsCleared();
    }
}
