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

import net.minecraft.util.GsonHelper;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonObject;
import net.minecraft.world.level.storage.loot.Serializer;
import org.apache.logging.log4j.LogManager;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.ValidationContext;
import net.minecraft.resources.ResourceLocation;
import org.apache.logging.log4j.Logger;

public class ConditionReference implements LootItemCondition {
    private static final Logger LOGGER;
    private final ResourceLocation name;
    
    private ConditionReference(final ResourceLocation uh) {
        this.name = uh;
    }
    
    @Override
    public LootItemConditionType getType() {
        return LootItemConditions.REFERENCE;
    }
    
    @Override
    public void validate(final ValidationContext dbe) {
        if (dbe.hasVisitedCondition(this.name)) {
            dbe.reportProblem("Condition " + this.name + " is recursively called");
            return;
        }
        super.validate(dbe);
        final LootItemCondition ddm3 = dbe.resolveCondition(this.name);
        if (ddm3 == null) {
            dbe.reportProblem("Unknown condition table called " + this.name);
        }
        else {
            ddm3.validate(dbe.enterTable(".{" + this.name + "}", this.name));
        }
    }
    
    @Override
    public boolean test(final LootContext dat) {
        final LootItemCondition ddm3 = dat.getCondition(this.name);
        if (dat.addVisitedCondition(ddm3)) {
            try {
                return ddm3.test(dat);
            }
            finally {
                dat.removeVisitedCondition(ddm3);
            }
        }
        ConditionReference.LOGGER.warn("Detected infinite loop in loot tables");
        return false;
    }
    
    static {
        LOGGER = LogManager.getLogger();
    }
    
    public static class Serializer implements net.minecraft.world.level.storage.loot.Serializer<ConditionReference> {
        @Override
        public void serialize(final JsonObject jsonObject, final ConditionReference dde, final JsonSerializationContext jsonSerializationContext) {
            jsonObject.addProperty("name", dde.name.toString());
        }
        
        @Override
        public ConditionReference deserialize(final JsonObject jsonObject, final JsonDeserializationContext jsonDeserializationContext) {
            final ResourceLocation uh4 = new ResourceLocation(GsonHelper.getAsString(jsonObject, "name"));
            return new ConditionReference(uh4, null);
        }
    }
}
