package net.minecraft.data.models.blockstates;

import com.google.common.collect.ImmutableList;
import java.util.Map;
import java.util.Iterator;
import net.minecraft.Util;
import java.util.function.BiConsumer;
import com.google.gson.JsonObject;
import java.util.TreeMap;
import java.util.stream.Stream;
import com.mojang.datafixers.util.Pair;
import com.google.gson.JsonElement;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import net.minecraft.world.level.block.state.properties.Property;
import java.util.Set;
import java.util.List;
import net.minecraft.world.level.block.Block;

public class MultiVariantGenerator implements BlockStateGenerator {
    private final Block block;
    private final List<Variant> baseVariants;
    private final Set<Property<?>> seenProperties;
    private final List<PropertyDispatch> declaredPropertySets;
    
    private MultiVariantGenerator(final Block bvr, final List<Variant> list) {
        this.seenProperties = Sets.newHashSet();
        this.declaredPropertySets = Lists.newArrayList();
        this.block = bvr;
        this.baseVariants = list;
    }
    
    public MultiVariantGenerator with(final PropertyDispatch io) {
        // 
        // This method could not be decompiled.
        // 
        // Original Bytecode:
        // 
        //     1: invokevirtual   net/minecraft/data/models/blockstates/PropertyDispatch.getDefinedProperties:()Ljava/util/List;
        //     4: aload_0         /* this */
        //     5: invokedynamic   BootstrapMethod #0, accept:(Lnet/minecraft/data/models/blockstates/MultiVariantGenerator;)Ljava/util/function/Consumer;
        //    10: invokeinterface java/util/List.forEach:(Ljava/util/function/Consumer;)V
        //    15: aload_0         /* this */
        //    16: getfield        net/minecraft/data/models/blockstates/MultiVariantGenerator.declaredPropertySets:Ljava/util/List;
        //    19: aload_1         /* io */
        //    20: invokeinterface java/util/List.add:(Ljava/lang/Object;)Z
        //    25: pop            
        //    26: aload_0         /* this */
        //    27: areturn        
        //    MethodParameters:
        //  Name  Flags  
        //  ----  -----
        //  io    
        // 
        // The error that occurred was:
        // 
        // java.lang.IllegalStateException: Could not infer any expression.
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:374)
        //     at com.strobel.decompiler.ast.TypeAnalysis.run(TypeAnalysis.java:96)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:344)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:42)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:214)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:99)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethodBody(AstBuilder.java:782)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethod(AstBuilder.java:675)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:552)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:519)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:161)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createType(AstBuilder.java:150)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addType(AstBuilder.java:125)
        //     at cuchaz.enigma.SourceProvider.getSources(SourceProvider.java:85)
        //     at cuchaz.enigma.EnigmaProject$JarExport.decompileClass(EnigmaProject.java:241)
        //     at cuchaz.enigma.EnigmaProject$JarExport.lambda$decompile$1(EnigmaProject.java:230)
        //     at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
        //     at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1654)
        //     at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
        //     at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
        //     at java.base/java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:952)
        //     at java.base/java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:926)
        //     at java.base/java.util.stream.AbstractTask.compute(AbstractTask.java:327)
        //     at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:746)
        //     at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
        //     at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
        //     at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
        //     at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
        //     at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)
        // 
        throw new IllegalStateException("An error occurred while decompiling this method.");
    }
    
    @Override
    public JsonElement get() {
        Stream<Pair<Selector, List<Variant>>> stream2 = Stream.<Pair<Selector, List<Variant>>>of(Pair.of(Selector.empty(), this.baseVariants));
        for (final PropertyDispatch io4 : this.declaredPropertySets) {
            final Map<Selector, List<Variant>> map5 = io4.getEntries();
            final Selector ip3;
            final List<Variant> list4;
            stream2 = stream2.<Pair<Selector, List<Variant>>>flatMap(pair -> map5.entrySet().stream().map(entry -> {
                ip3 = ((Selector)pair.getFirst()).extend(entry.getKey());
                list4 = mergeVariants((List<Variant>)pair.getSecond(), (List<Variant>)entry.getValue());
                return Pair.of(ip3, list4);
            }));
        }
        final Map<String, JsonElement> map6 = new TreeMap<String, JsonElement>();
        final JsonElement jsonElement;
        stream2.forEach(pair -> jsonElement = map6.put(((Selector)pair.getFirst()).getKey(), Variant.convertList((List<Variant>)pair.getSecond())));
        final JsonObject jsonObject2 = new JsonObject();
        jsonObject2.add("variants", Util.<JsonObject>make(new JsonObject(), jsonObject -> map6.forEach(jsonObject::add)));
        return jsonObject2;
    }
    
    private static List<Variant> mergeVariants(final List<Variant> list1, final List<Variant> list2) {
        final ImmutableList.Builder<Variant> builder3 = ImmutableList.<Variant>builder();
        list1.forEach(iq -> list2.forEach(iq3 -> builder3.add(Variant.merge(iq, iq3))));
        return builder3.build();
    }
    
    @Override
    public Block getBlock() {
        return this.block;
    }
    
    public static MultiVariantGenerator multiVariant(final Block bvr) {
        return new MultiVariantGenerator(bvr, ImmutableList.<Variant>of(Variant.variant()));
    }
    
    public static MultiVariantGenerator multiVariant(final Block bvr, final Variant iq) {
        return new MultiVariantGenerator(bvr, ImmutableList.<Variant>of(iq));
    }
    
    public static MultiVariantGenerator multiVariant(final Block bvr, final Variant... arr) {
        return new MultiVariantGenerator(bvr, ImmutableList.<Variant>copyOf(arr));
    }
}
