package net.minecraft.client.renderer.debug;

import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.client.multiplayer.ClientChunkCache;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.dimension.DimensionType;
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 dbn) {
        this.lastUpdateTime = Double.MIN_VALUE;
        this.minecraft = dbn;
    }
    
    @Override
    public void render(final PoseStack cyl, final MultiBufferSource dqt, 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 edm12 = this.minecraft.getSingleplayerServer();
            if (edm12 != null) {
                this.data = new ChunkData(edm12, 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 bjh17 = entry16.getKey();
                String string18 = entry16.getValue();
                if (map12 != null) {
                    string18 += map12.get(bjh17);
                }
                final String[] arr19 = string18.split("\n");
                int integer20 = 0;
                for (final String string19 : arr19) {
                    DebugRenderer.renderFloatingText(string19, (bjh17.x << 4) + 8, double7 + integer20, (bjh17.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 edm, final double double3, final double double4) {
            final ClientLevel dno8 = ChunkDebugRenderer.this.minecraft.level;
            final DimensionType cbi9 = ChunkDebugRenderer.this.minecraft.level.dimension.getType();
            if (edm.getLevel(cbi9) != null) {
                final ServerLevel xd10 = edm.getLevel(cbi9);
            }
            else {
                final ServerLevel xd10 = null;
            }
            final int integer11 = (int)double3 >> 4;
            final int integer12 = (int)double4 >> 4;
            final ImmutableMap.Builder<ChunkPos, String> builder13 = ImmutableMap.<ChunkPos, String>builder();
            final ClientChunkCache dnm14 = dno8.getChunkSource();
            for (int integer13 = integer11 - 12; integer13 <= integer11 + 12; ++integer13) {
                for (int integer14 = integer12 - 12; integer14 <= integer12 + 12; ++integer14) {
                    final ChunkPos bjh17 = new ChunkPos(integer13, integer14);
                    String string18 = "";
                    final LevelChunk cal19 = dnm14.getChunk(integer13, integer14, false);
                    string18 += "Client: ";
                    if (cal19 == null) {
                        string18 += "0n/a\n";
                    }
                    else {
                        string18 += (cal19.isEmpty() ? " E" : "");
                        string18 += "\n";
                    }
                    builder13.put(bjh17, string18);
                }
            }
            this.clientData = builder13.build();
            final ImmutableMap.Builder<ChunkPos, String> builder14;
            final ServerLevel serverLevel;
            final ServerChunkCache xb6;
            final int n;
            int integer15;
            final int n2;
            int integer16;
            ChunkPos bjh18;
            this.serverData = edm.submit(() -> {
                builder14 = ImmutableMap.<ChunkPos, String>builder();
                xb6 = serverLevel.getChunkSource();
                for (integer15 = n - 12; integer15 <= n + 12; ++integer15) {
                    for (integer16 = n2 - 12; integer16 <= n2 + 12; ++integer16) {
                        bjh18 = new ChunkPos(integer15, integer16);
                        builder14.put(bjh18, "Server: " + xb6.getChunkDebugData(bjh18));
                    }
                }
                return builder14.build();
            });
        }
    }
}
