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

import net.minecraft.util.GsonHelper;
import com.google.gson.JsonDeserializationContext;
import org.apache.commons.lang3.ArrayUtils;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonObject;
import net.minecraft.world.level.storage.loot.Serializer;
import com.google.common.collect.Lists;
import java.util.List;
import net.minecraft.world.level.storage.loot.predicates.ConditionUserBuilder;
import java.util.function.Function;
import net.minecraft.world.level.storage.loot.ValidationContext;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.storage.loot.predicates.LootItemConditions;
import net.minecraft.world.level.storage.loot.LootContext;
import java.util.function.Predicate;
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;

public abstract class LootItemConditionalFunction implements LootItemFunction {
    protected final LootItemCondition[] predicates;
    private final Predicate<LootContext> compositePredicates;
    
    protected LootItemConditionalFunction(final LootItemCondition[] arr) {
        this.predicates = arr;
        this.compositePredicates = LootItemConditions.<LootContext>andConditions(arr);
    }
    
    @Override
    public final ItemStack apply(final ItemStack bki, final LootContext dat) {
        return this.compositePredicates.test(dat) ? this.run(bki, dat) : bki;
    }
    
    protected abstract ItemStack run(final ItemStack bki, final LootContext dat);
    
    @Override
    public void validate(final ValidationContext dbe) {
        super.validate(dbe);
        for (int integer3 = 0; integer3 < this.predicates.length; ++integer3) {
            this.predicates[integer3].validate(dbe.forChild(".conditions[" + integer3 + "]"));
        }
    }
    
    protected static Builder<?> simpleBuilder(final Function<LootItemCondition[], LootItemFunction> function) {
        return new DummyBuilder(function);
    }
    
    public abstract static class Builder<T extends Builder<T>> implements LootItemFunction.Builder, ConditionUserBuilder<T> {
        private final List<LootItemCondition> conditions;
        
        public Builder() {
            this.conditions = Lists.newArrayList();
        }
        
        @Override
        public T when(final LootItemCondition.Builder a) {
            this.conditions.add(a.build());
            return this.getThis();
        }
        
        @Override
        public final T unwrap() {
            return this.getThis();
        }
        
        protected abstract T getThis();
        
        protected LootItemCondition[] getConditions() {
            return this.conditions.<LootItemCondition>toArray(new LootItemCondition[0]);
        }
    }
    
    static final class DummyBuilder extends Builder<DummyBuilder> {
        private final Function<LootItemCondition[], LootItemFunction> constructor;
        
        public DummyBuilder(final Function<LootItemCondition[], LootItemFunction> function) {
            this.constructor = function;
        }
        
        @Override
        protected DummyBuilder getThis() {
            return this;
        }
        
        @Override
        public LootItemFunction build() {
            return this.constructor.apply(this.getConditions());
        }
    }
    
    public abstract static class Serializer<T extends LootItemConditionalFunction> implements net.minecraft.world.level.storage.loot.Serializer<T> {
        @Override
        public void serialize(final JsonObject jsonObject, final T dcg, final JsonSerializationContext jsonSerializationContext) {
            if (!ArrayUtils.isEmpty((Object[])dcg.predicates)) {
                jsonObject.add("conditions", jsonSerializationContext.serialize(dcg.predicates));
            }
        }
        
        @Override
        public final T deserialize(final JsonObject jsonObject, final JsonDeserializationContext jsonDeserializationContext) {
            final LootItemCondition[] arr4 = GsonHelper.<LootItemCondition[]>getAsObject(jsonObject, "conditions", new LootItemCondition[0], jsonDeserializationContext, LootItemCondition[].class);
            return this.deserialize(jsonObject, jsonDeserializationContext, arr4);
        }
        
        public abstract T deserialize(final JsonObject jsonObject, final JsonDeserializationContext jsonDeserializationContext, final LootItemCondition[] arr);
    }
}
