// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.builtin.hytalegenerator.datastructures;

import java.util.Collections;
import java.util.Comparator;
import java.util.Collection;
import java.util.function.Consumer;
import java.util.Iterator;
import java.util.HashMap;
import java.util.List;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.Map;

public class TieredList<E>
{
    @Nonnull
    private final Map<Integer, ArrayList<E>> elements;
    private final int tiers;
    private List<Integer> sortedTierList;
    
    public TieredList() {
        this(0);
    }
    
    public TieredList(final int tiers) {
        if (tiers < 0) {
            throw new IllegalArgumentException("negative number of tiers");
        }
        this.tiers = tiers;
        this.elements = new HashMap<Integer, ArrayList<E>>();
        for (int tier = 0; tier < tiers; ++tier) {
            this.elements.put(tier, new ArrayList<E>());
        }
        this.updateSortedTierList();
    }
    
    @Nonnull
    public TieredList<E> addTier(final int tier) {
        if (this.tierExists(tier)) {
            throw new IllegalArgumentException("tier already exists " + tier);
        }
        this.elements.put(tier, new ArrayList<E>());
        this.updateSortedTierList();
        return this;
    }
    
    @Nonnull
    public TieredList<E> removeTier(final int tier) {
        if (!this.tierExists(tier)) {
            return this;
        }
        this.elements.remove(tier);
        this.updateSortedTierList();
        return this;
    }
    
    public void add(@Nonnull final E element, final int tier) {
        if (element == null) {
            throw new NullPointerException();
        }
        if (!this.tierExists(tier)) {
            this.addTier(tier);
        }
        this.elements.get(tier).add(element);
    }
    
    public boolean isEmpty() {
        for (final List<E> list : this.elements.values()) {
            if (!list.isEmpty()) {
                return false;
            }
        }
        return true;
    }
    
    public E peek() {
        for (int tier = 0; tier < this.tiers; ++tier) {
            final List<E> tierElements = this.elements.get(tier);
            if (!tierElements.isEmpty()) {
                return tierElements.getFirst();
            }
        }
        throw new IllegalStateException("queue is empty");
    }
    
    public E remove() {
        for (int tier = 0; tier < this.tiers; ++tier) {
            final List<E> tierElements = this.elements.get(tier);
            if (!tierElements.isEmpty()) {
                return tierElements.removeFirst();
            }
        }
        throw new IllegalStateException("queue is empty");
    }
    
    public int size() {
        int size = 0;
        for (final List<E> list : this.elements.values()) {
            size += list.size();
        }
        return size;
    }
    
    public int size(final int tier) {
        if (!this.tierExists(tier)) {
            return 0;
        }
        return this.elements.get(tier).size();
    }
    
    @Nonnull
    public TieredList<E> forEach(final int tier, @Nonnull final Consumer<? super E> consumer) {
        if (!this.tierExists(tier)) {
            return this;
        }
        this.elements.get(tier).forEach(consumer);
        return this;
    }
    
    @Nonnull
    public TieredList<E> removeEach(final int tier, @Nonnull final Consumer<? super E> consumer) {
        if (!this.tierExists(tier)) {
            return this;
        }
        List<E> tierList = this.elements.get(tier);
        for (final E e : tierList) {
            consumer.accept(e);
        }
        tierList = new ArrayList<E>();
        return this;
    }
    
    @Nonnull
    public TieredList<E> forEach(@Nonnull final Consumer<? super E> consumer) {
        final ArrayList<Integer> tiers = new ArrayList<Integer>(this.getTiers());
        tiers.sort(Comparator.naturalOrder());
        for (final int tier : tiers) {
            this.forEach(tier, consumer);
        }
        return this;
    }
    
    @Nonnull
    public TieredList<E> removeEach(@Nonnull final Consumer<? super E> consumer) {
        for (final int tier : this.getTiers()) {
            this.removeEach(tier, consumer);
        }
        return this;
    }
    
    @Nonnull
    public Iterator<E> iterator(final int tier) {
        if (!this.tierExists(tier)) {
            throw new IllegalArgumentException("tier doesn't exist");
        }
        return this.elements.get(tier).iterator();
    }
    
    @Nonnull
    public List<E> listOf(final int tier) {
        if (!this.tierExists(tier)) {
            throw new IllegalArgumentException("tier doesn't exist");
        }
        return Collections.unmodifiableList((List<? extends E>)this.elements.get(tier));
    }
    
    public boolean tierExists(final int tier) {
        return this.elements.containsKey(tier);
    }
    
    public List<Integer> getTiers() {
        return this.sortedTierList;
    }
    
    private void updateSortedTierList() {
        List<Integer> tierList = new ArrayList<Integer>(this.elements.keySet());
        tierList.sort(Comparator.naturalOrder());
        tierList = Collections.unmodifiableList((List<? extends Integer>)tierList);
        this.sortedTierList = tierList;
    }
    
    @Nonnull
    @Override
    public String toString() {
        return "TieredList{elements=" + String.valueOf(this.elements) + ", tiers=" + this.tiers + ", sortedTierList=" + String.valueOf(this.sortedTierList);
    }
}
