package net.minecraft.world.level.storage.loot.parameters;

import net.minecraft.world.level.storage.loot.LootContextUser;
import net.minecraft.world.level.storage.loot.ValidationContext;
import com.google.common.base.Joiner;
import com.google.common.collect.Sets;
import java.util.Collection;
import com.google.common.collect.ImmutableSet;
import java.util.Set;

public class LootContextParamSet {
    private final Set<LootContextParam<?>> required;
    private final Set<LootContextParam<?>> all;
    
    private LootContextParamSet(final Set<LootContextParam<?>> set1, final Set<LootContextParam<?>> set2) {
        this.required = ImmutableSet.copyOf(set1);
        this.all = ImmutableSet.copyOf(Sets.union(set1, set2));
    }
    
    public Set<LootContextParam<?>> getRequired() {
        return this.required;
    }
    
    public Set<LootContextParam<?>> getAllowed() {
        return this.all;
    }
    
    @Override
    public String toString() {
        return "[" + Joiner.on(", ").join(this.all.stream().map(dcx -> (this.required.contains(dcx) ? "!" : "") + dcx.getName()).iterator()) + "]";
    }
    
    public void validateUser(final ValidationContext dbe, final LootContextUser dau) {
        final Set<LootContextParam<?>> set4 = dau.getReferencedContextParams();
        final Set<LootContextParam<?>> set5 = Sets.<LootContextParam<?>>difference(set4, this.all);
        if (!set5.isEmpty()) {
            dbe.reportProblem("Parameters " + set5 + " are not provided in this context");
        }
    }
    
    public static class Builder {
        private final Set<LootContextParam<?>> required;
        private final Set<LootContextParam<?>> optional;
        
        public Builder() {
            this.required = Sets.<LootContextParam<?>>newIdentityHashSet();
            this.optional = Sets.<LootContextParam<?>>newIdentityHashSet();
        }
        
        public Builder required(final LootContextParam<?> dcx) {
            if (this.optional.contains(dcx)) {
                throw new IllegalArgumentException("Parameter " + dcx.getName() + " is already optional");
            }
            this.required.add(dcx);
            return this;
        }
        
        public Builder optional(final LootContextParam<?> dcx) {
            if (this.required.contains(dcx)) {
                throw new IllegalArgumentException("Parameter " + dcx.getName() + " is already required");
            }
            this.optional.add(dcx);
            return this;
        }
        
        public LootContextParamSet build() {
            return new LootContextParamSet(this.required, this.optional, null);
        }
    }
}
