package net.minecraft.client.gui.font;

import org.apache.logging.log4j.LogManager;
import net.minecraft.util.profiling.InactiveProfiler;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import javax.annotation.Nullable;
import java.util.Collections;
import com.google.gson.JsonArray;
import java.io.InputStream;
import java.util.Iterator;
import com.google.gson.Gson;
import java.io.IOException;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.font.providers.GlyphProviderBuilderType;
import net.minecraft.util.GsonHelper;
import com.google.gson.JsonObject;
import java.io.Reader;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import net.minecraft.server.packs.resources.Resource;
import com.google.common.collect.Lists;
import com.google.gson.GsonBuilder;
import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.server.packs.resources.ResourceManager;
import com.mojang.blaze3d.font.GlyphProvider;
import java.util.List;
import net.minecraft.server.packs.resources.SimplePreparableReloadListener;
import com.google.common.collect.Maps;
import net.minecraft.server.packs.resources.PreparableReloadListener;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.gui.Font;
import net.minecraft.resources.ResourceLocation;
import java.util.Map;
import org.apache.logging.log4j.Logger;

public class FontManager implements AutoCloseable {
    private static final Logger LOGGER;
    private final Map<ResourceLocation, Font> fonts;
    private final TextureManager textureManager;
    private boolean forceUnicode;
    private final PreparableReloadListener reloadListener;
    
    public FontManager(final TextureManager eak, final boolean boolean2) {
        this.fonts = Maps.newHashMap();
        this.reloadListener = new SimplePreparableReloadListener<Map<ResourceLocation, List<GlyphProvider>>>() {
            @Override
            protected Map<ResourceLocation, List<GlyphProvider>> prepare(final ResourceManager zb, final ProfilerFiller aio) {
                aio.startTick();
                final Gson gson4 = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
                final Map<ResourceLocation, List<GlyphProvider>> map5 = Maps.newHashMap();
                for (final ResourceLocation sm7 : zb.listResources("font", string -> string.endsWith(".json"))) {
                    final String string2 = sm7.getPath();
                    final ResourceLocation sm8 = new ResourceLocation(sm7.getNamespace(), string2.substring("font/".length(), string2.length() - ".json".length()));
                    final List<GlyphProvider> list10 = map5.computeIfAbsent(sm8, sm -> Lists.<GlyphProvider>newArrayList(new AllMissingGlyphProvider()));
                    aio.push(sm8::toString);
                    try {
                        for (final Resource za12 : zb.getResources(sm7)) {
                            aio.push(za12::getSourceName);
                            try (final InputStream inputStream13 = za12.getInputStream();
                                 final Reader reader15 = new BufferedReader(new InputStreamReader(inputStream13, StandardCharsets.UTF_8))) {
                                aio.push("reading");
                                final JsonArray jsonArray17 = GsonHelper.getAsJsonArray(GsonHelper.<JsonObject>fromJson(gson4, reader15, JsonObject.class), "providers");
                                aio.popPush("parsing");
                                for (int integer18 = jsonArray17.size() - 1; integer18 >= 0; --integer18) {
                                    final JsonObject jsonObject19 = GsonHelper.convertToJsonObject(jsonArray17.get(integer18), "providers[" + integer18 + "]");
                                    try {
                                        final String string3 = GsonHelper.getAsString(jsonObject19, "type");
                                        final GlyphProviderBuilderType der21 = GlyphProviderBuilderType.byName(string3);
                                        if (!FontManager.this.forceUnicode || der21 == GlyphProviderBuilderType.LEGACY_UNICODE || !sm8.equals(Minecraft.DEFAULT_FONT)) {
                                            aio.push(string3);
                                            list10.add(der21.create(jsonObject19).create(zb));
                                            aio.pop();
                                        }
                                    }
                                    catch (RuntimeException runtimeException20) {
                                        FontManager.LOGGER.warn("Unable to read definition '{}' in fonts.json in resourcepack: '{}': {}", sm8, za12.getSourceName(), runtimeException20.getMessage());
                                    }
                                }
                                aio.pop();
                            }
                            catch (RuntimeException runtimeException21) {
                                FontManager.LOGGER.warn("Unable to load font '{}' in fonts.json in resourcepack: '{}': {}", sm8, za12.getSourceName(), runtimeException21.getMessage());
                            }
                            aio.pop();
                        }
                    }
                    catch (IOException iOException11) {
                        FontManager.LOGGER.warn("Unable to load font '{}' in fonts.json: {}", sm8, iOException11.getMessage());
                    }
                    aio.push("caching");
                    for (char character11 = '\0'; character11 < '\uffff'; ++character11) {
                        if (character11 != ' ') {
                            for (final GlyphProvider cwz13 : Lists.<GlyphProvider>reverse(list10)) {
                                if (cwz13.getGlyph(character11) != null) {
                                    break;
                                }
                            }
                        }
                    }
                    aio.pop();
                    aio.pop();
                }
                aio.endTick();
                return map5;
            }
            
            @Override
            protected void apply(final Map<ResourceLocation, List<GlyphProvider>> map, final ResourceManager zb, final ProfilerFiller aio) {
                // 
                // This method could not be decompiled.
                // 
                // Original Bytecode:
                // 
                //     1: invokeinterface net/minecraft/util/profiling/ProfilerFiller.startTick:()V
                //     6: aload_3         /* aio */
                //     7: ldc_w           "reloading"
                //    10: invokeinterface net/minecraft/util/profiling/ProfilerFiller.push:(Ljava/lang/String;)V
                //    15: aload_0         /* this */
                //    16: getfield        net/minecraft/client/gui/font/FontManager$1.this$0:Lnet/minecraft/client/gui/font/FontManager;
                //    19: invokestatic    net/minecraft/client/gui/font/FontManager.access$200:(Lnet/minecraft/client/gui/font/FontManager;)Ljava/util/Map;
                //    22: invokeinterface java/util/Map.keySet:()Ljava/util/Set;
                //    27: invokeinterface java/util/Set.stream:()Ljava/util/stream/Stream;
                //    32: aload_1         /* map */
                //    33: invokeinterface java/util/Map.keySet:()Ljava/util/Set;
                //    38: invokeinterface java/util/Set.stream:()Ljava/util/stream/Stream;
                //    43: invokestatic    java/util/stream/Stream.concat:(Ljava/util/stream/Stream;Ljava/util/stream/Stream;)Ljava/util/stream/Stream;
                //    46: invokeinterface java/util/stream/Stream.distinct:()Ljava/util/stream/Stream;
                //    51: aload_0         /* this */
                //    52: aload_1         /* map */
                //    53: invokedynamic   BootstrapMethod #4, accept:(Lnet/minecraft/client/gui/font/FontManager$1;Ljava/util/Map;)Ljava/util/function/Consumer;
                //    58: invokeinterface java/util/stream/Stream.forEach:(Ljava/util/function/Consumer;)V
                //    63: aload_3         /* aio */
                //    64: invokeinterface net/minecraft/util/profiling/ProfilerFiller.pop:()V
                //    69: aload_3         /* aio */
                //    70: invokeinterface net/minecraft/util/profiling/ProfilerFiller.endTick:()V
                //    75: return         
                //    Signature:
                //  (Ljava/util/Map<Lnet/minecraft/resources/ResourceLocation;Ljava/util/List<Lcom/mojang/blaze3d/font/GlyphProvider;>;>;Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/util/profiling/ProfilerFiller;)V
                //    MethodParameters:
                //  Name  Flags  
                //  ----  -----
                //  map   
                //  zb    
                //  aio   
                // 
                // 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.AstMethodBodyBuilder.transformCall(AstMethodBodyBuilder.java:1164)
                //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.transformByteCode(AstMethodBodyBuilder.java:1009)
                //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.transformExpression(AstMethodBodyBuilder.java:540)
                //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.transformByteCode(AstMethodBodyBuilder.java:554)
                //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.transformExpression(AstMethodBodyBuilder.java:540)
                //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.transformNode(AstMethodBodyBuilder.java:392)
                //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.transformBlock(AstMethodBodyBuilder.java:333)
                //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:294)
                //     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.createConstructor(AstBuilder.java:713)
                //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:549)
                //     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 String getName() {
                return "FontManager";
            }
        };
        this.textureManager = eak;
        this.forceUnicode = boolean2;
    }
    
    @Nullable
    public Font get(final ResourceLocation sm) {
        // 
        // This method could not be decompiled.
        // 
        // Original Bytecode:
        // 
        //     1: getfield        net/minecraft/client/gui/font/FontManager.fonts:Ljava/util/Map;
        //     4: aload_1         /* sm */
        //     5: aload_0         /* this */
        //     6: invokedynamic   BootstrapMethod #0, apply:(Lnet/minecraft/client/gui/font/FontManager;)Ljava/util/function/Function;
        //    11: invokeinterface java/util/Map.computeIfAbsent:(Ljava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object;
        //    16: checkcast       Lnet/minecraft/client/gui/Font;
        //    19: areturn        
        //    MethodParameters:
        //  Name  Flags  
        //  ----  -----
        //  sm    
        // 
        // 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.");
    }
    
    public void setForceUnicode(final boolean boolean1, final Executor executor2, final Executor executor3) {
        if (boolean1 == this.forceUnicode) {
            return;
        }
        this.forceUnicode = boolean1;
        final ResourceManager zb5 = Minecraft.getInstance().getResourceManager();
        final PreparableReloadListener.PreparationBarrier a6 = new PreparableReloadListener.PreparationBarrier() {
            @Override
            public <T> CompletableFuture<T> wait(final T object) {
                return CompletableFuture.<T>completedFuture(object);
            }
        };
        this.reloadListener.reload(a6, zb5, InactiveProfiler.INACTIVE, InactiveProfiler.INACTIVE, executor2, executor3);
    }
    
    public PreparableReloadListener getReloadListener() {
        return this.reloadListener;
    }
    
    @Override
    public void close() {
        this.fonts.values().forEach(Font::close);
    }
    
    static {
        LOGGER = LogManager.getLogger();
    }
}
