package net.minecraft.client.renderer.texture;

import org.apache.logging.log4j.LogManager;
import net.minecraft.Util;
import org.apache.commons.io.FileUtils;
import java.net.URL;
import java.net.HttpURLConnection;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.IOException;
import net.minecraft.server.packs.resources.ResourceManager;
import com.mojang.blaze3d.platform.TextureUtil;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Minecraft;
import com.mojang.blaze3d.platform.NativeImage;
import net.minecraft.resources.ResourceLocation;
import java.util.concurrent.CompletableFuture;
import javax.annotation.Nullable;
import java.io.File;
import org.apache.logging.log4j.Logger;

public class HttpTexture extends SimpleTexture {
    private static final Logger LOGGER;
    @Nullable
    private final File file;
    private final String urlString;
    private final boolean processLegacySkin;
    @Nullable
    private final Runnable onDownloaded;
    @Nullable
    private CompletableFuture<?> future;
    private boolean uploaded;
    
    public HttpTexture(@Nullable final File file, final String string, final ResourceLocation uh, final boolean boolean4, @Nullable final Runnable runnable) {
        super(uh);
        this.file = file;
        this.urlString = string;
        this.processLegacySkin = boolean4;
        this.onDownloaded = runnable;
    }
    
    private void loadCallback(final NativeImage dgs) {
        if (this.onDownloaded != null) {
            this.onDownloaded.run();
        }
        Minecraft.getInstance().execute(() -> {
            this.uploaded = true;
            if (!RenderSystem.isOnRenderThread()) {
                RenderSystem.recordRenderCall(() -> this.upload(dgs));
            }
            else {
                this.upload(dgs);
            }
        });
    }
    
    private void upload(final NativeImage dgs) {
        TextureUtil.prepareImage(this.getId(), dgs.getWidth(), dgs.getHeight());
        dgs.upload(0, 0, 0, true);
    }
    
    @Override
    public void load(final ResourceManager abc) throws IOException {
        Minecraft.getInstance().execute(() -> {
            if (!this.uploaded) {
                try {
                    super.load(abc);
                }
                catch (IOException iOException3) {
                    HttpTexture.LOGGER.warn("Failed to load texture: {}", this.location, iOException3);
                }
                this.uploaded = true;
            }
            return;
        });
        if (this.future != null) {
            return;
        }
        NativeImage dgs3;
        if (this.file != null && this.file.isFile()) {
            HttpTexture.LOGGER.debug("Loading http texture from local cache ({})", this.file);
            final FileInputStream fileInputStream4 = new FileInputStream(this.file);
            dgs3 = this.load(fileInputStream4);
        }
        else {
            dgs3 = null;
        }
        if (dgs3 != null) {
            this.loadCallback(dgs3);
            return;
        }
        HttpURLConnection httpURLConnection2;
        InputStream inputStream3;
        NativeImage dgs4;
        this.future = CompletableFuture.runAsync(() -> {
            httpURLConnection2 = null;
            HttpTexture.LOGGER.debug("Downloading http texture from {} to {}", this.urlString, this.file);
            try {
                httpURLConnection2 = (HttpURLConnection)new URL(this.urlString).openConnection(Minecraft.getInstance().getProxy());
                httpURLConnection2.setDoInput(true);
                httpURLConnection2.setDoOutput(false);
                httpURLConnection2.connect();
                if (httpURLConnection2.getResponseCode() / 100 == 2) {
                    if (this.file != null) {
                        FileUtils.copyInputStreamToFile(httpURLConnection2.getInputStream(), this.file);
                        inputStream3 = new FileInputStream(this.file);
                    }
                    else {
                        inputStream3 = httpURLConnection2.getInputStream();
                    }
                    Minecraft.getInstance().execute(() -> {
                        dgs4 = this.load(inputStream3);
                        if (dgs4 != null) {
                            this.loadCallback(dgs4);
                        }
                    });
                }
            }
            catch (Exception exception3) {
                HttpTexture.LOGGER.error("Couldn't download http texture", (Throwable)exception3);
            }
            finally {
                if (httpURLConnection2 != null) {
                    httpURLConnection2.disconnect();
                }
            }
        }, Util.backgroundExecutor());
    }
    
    @Nullable
    private NativeImage load(final InputStream inputStream) {
        NativeImage dgs3 = null;
        try {
            dgs3 = NativeImage.read(inputStream);
            if (this.processLegacySkin) {
                dgs3 = processLegacySkin(dgs3);
            }
        }
        catch (IOException iOException4) {
            HttpTexture.LOGGER.warn("Error while loading the skin texture", (Throwable)iOException4);
        }
        return dgs3;
    }
    
    private static NativeImage processLegacySkin(NativeImage dgs) {
        final boolean boolean2 = dgs.getHeight() == 32;
        if (boolean2) {
            final NativeImage dgs2 = new NativeImage(64, 64, true);
            dgs2.copyFrom(dgs);
            dgs.close();
            dgs = dgs2;
            dgs.fillRect(0, 32, 64, 32, 0);
            dgs.copyRect(4, 16, 16, 32, 4, 4, true, false);
            dgs.copyRect(8, 16, 16, 32, 4, 4, true, false);
            dgs.copyRect(0, 20, 24, 32, 4, 12, true, false);
            dgs.copyRect(4, 20, 16, 32, 4, 12, true, false);
            dgs.copyRect(8, 20, 8, 32, 4, 12, true, false);
            dgs.copyRect(12, 20, 16, 32, 4, 12, true, false);
            dgs.copyRect(44, 16, -8, 32, 4, 4, true, false);
            dgs.copyRect(48, 16, -8, 32, 4, 4, true, false);
            dgs.copyRect(40, 20, 0, 32, 4, 12, true, false);
            dgs.copyRect(44, 20, -8, 32, 4, 12, true, false);
            dgs.copyRect(48, 20, -16, 32, 4, 12, true, false);
            dgs.copyRect(52, 20, -8, 32, 4, 12, true, false);
        }
        setNoAlpha(dgs, 0, 0, 32, 16);
        if (boolean2) {
            doNotchTransparencyHack(dgs, 32, 0, 64, 32);
        }
        setNoAlpha(dgs, 0, 16, 64, 32);
        setNoAlpha(dgs, 16, 48, 48, 64);
        return dgs;
    }
    
    private static void doNotchTransparencyHack(final NativeImage dgs, final int integer2, final int integer3, final int integer4, final int integer5) {
        for (int integer6 = integer2; integer6 < integer4; ++integer6) {
            for (int integer7 = integer3; integer7 < integer5; ++integer7) {
                final int integer8 = dgs.getPixelRGBA(integer6, integer7);
                if ((integer8 >> 24 & 0xFF) < 128) {
                    return;
                }
            }
        }
        for (int integer6 = integer2; integer6 < integer4; ++integer6) {
            for (int integer7 = integer3; integer7 < integer5; ++integer7) {
                dgs.setPixelRGBA(integer6, integer7, dgs.getPixelRGBA(integer6, integer7) & 0xFFFFFF);
            }
        }
    }
    
    private static void setNoAlpha(final NativeImage dgs, final int integer2, final int integer3, final int integer4, final int integer5) {
        for (int integer6 = integer2; integer6 < integer4; ++integer6) {
            for (int integer7 = integer3; integer7 < integer5; ++integer7) {
                dgs.setPixelRGBA(integer6, integer7, dgs.getPixelRGBA(integer6, integer7) | 0xFF000000);
            }
        }
    }
    
    static {
        LOGGER = LogManager.getLogger();
    }
}
