package net.minecraft.client.renderer.debug;

import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.client.multiplayer.ClientChunkCache;
import net.minecraft.world.level.Level;
import net.minecraft.resources.ResourceKey;
import net.minecraft.client.multiplayer.ClientLevel;
import com.google.common.collect.ImmutableMap;
import java.util.concurrent.CompletableFuture;
import java.util.Iterator;
import net.minecraft.client.server.IntegratedServer;
import net.minecraft.world.level.ChunkPos;
import java.util.Map;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.Util;
import net.minecraft.client.renderer.MultiBufferSource;
import com.mojang.blaze3d.vertex.PoseStack;
import javax.annotation.Nullable;
import net.minecraft.client.Minecraft;

public class ChunkDebugRenderer implements DebugRenderer.SimpleDebugRenderer {
    private final Minecraft minecraft;
    private double lastUpdateTime;
    private final int radius = 12;
    @Nullable
    private ChunkData data;
    
    public ChunkDebugRenderer(final Minecraft dlx) {
        this.lastUpdateTime = Double.MIN_VALUE;
        this.minecraft = dlx;
    }
    
    @Override
    public void render(final PoseStack dhl, final MultiBufferSource ebz, final double double3, final double double4, final double double5) {
        final double double6 = (double)Util.getNanos();
        if (double6 - this.lastUpdateTime > 3.0E9) {
            this.lastUpdateTime = double6;
            final IntegratedServer eoz12 = this.minecraft.getSingleplayerServer();
            if (eoz12 != null) {
                this.data = new ChunkData(eoz12, double3, double5);
            }
            else {
                this.data = null;
            }
        }
        if (this.data != null) {
            RenderSystem.enableBlend();
            RenderSystem.defaultBlendFunc();
            RenderSystem.lineWidth(2.0f);
            RenderSystem.disableTexture();
            RenderSystem.depthMask(false);
            final Map<ChunkPos, String> map12 = this.data.serverData.getNow(null);
            final double double7 = this.minecraft.gameRenderer.getMainCamera().getPosition().y * 0.85;
            for (final Map.Entry<ChunkPos, String> entry16 : this.data.clientData.entrySet()) {
                final ChunkPos bph17 = entry16.getKey();
                String string18 = entry16.getValue();
                if (map12 != null) {
                    string18 += map12.get(bph17);
                }
                final String[] arr19 = string18.split("\n");
                int integer20 = 0;
                for (final String string19 : arr19) {
                    DebugRenderer.renderFloatingText(string19, (bph17.x << 4) + 8, double7 + integer20, (bph17.z << 4) + 8, -1, 0.15f);
                    integer20 -= 2;
                }
            }
            RenderSystem.depthMask(true);
            RenderSystem.enableTexture();
            RenderSystem.disableBlend();
        }
    }
    
    final class ChunkData {
        private final Map<ChunkPos, String> clientData;
        private final CompletableFuture<Map<ChunkPos, String>> serverData;
        
        private ChunkData(final IntegratedServer eoz, final double double3, final double double4) {
            final ClientLevel dym8 = ChunkDebugRenderer.this.minecraft.level;
            final ResourceKey<Level> ug9 = dym8.dimension();
            final int integer10 = (int)double3 >> 4;
            final int integer11 = (int)double4 >> 4;
            final ImmutableMap.Builder<ChunkPos, String> builder12 = ImmutableMap.<ChunkPos, String>builder();
            final ClientChunkCache dyk13 = dym8.getChunkSource();
            for (int integer12 = integer10 - 12; integer12 <= integer10 + 12; ++integer12) {
                for (int integer13 = integer11 - 12; integer13 <= integer11 + 12; ++integer13) {
                    final ChunkPos bph16 = new ChunkPos(integer12, integer13);
                    String string17 = "";
                    final LevelChunk chj18 = dyk13.getChunk(integer12, integer13, false);
                    string17 += "Client: ";
                    if (chj18 == null) {
                        string17 += "0n/a\n";
                    }
                    else {
                        string17 += (chj18.isEmpty() ? " E" : "");
                        string17 += "\n";
                    }
                    builder12.put(bph16, string17);
                }
            }
            this.clientData = builder12.build();
            final ResourceKey<Level> ug10;
            final ServerLevel zd6;
            ImmutableMap.Builder<ChunkPos, String> builder13;
            ServerChunkCache zb8;
            final int n;
            int integer14;
            final int n2;
            int integer15;
            ChunkPos bph17;
            this.serverData = eoz.<Map<ChunkPos, String>>submit(() -> {
                zd6 = eoz.getLevel(ug10);
                if (zd6 == null) {
                    return ImmutableMap.of();
                }
                else {
                    builder13 = ImmutableMap.<ChunkPos, String>builder();
                    zb8 = zd6.getChunkSource();
                    for (integer14 = n - 12; integer14 <= n + 12; ++integer14) {
                        for (integer15 = n2 - 12; integer15 <= n2 + 12; ++integer15) {
                            bph17 = new ChunkPos(integer14, integer15);
                            builder13.put(bph17, "Server: " + zb8.getChunkDebugData(bph17));
                        }
                    }
                    return (ImmutableMap<Object, Object>)builder13.build();
                }
            });
        }
    }
}
