package net.minecraft.client.resources;

import java.util.HashMap;
import net.minecraft.Util;
import com.mojang.blaze3d.systems.RenderSystem;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap;
import com.mojang.authlib.minecraft.InsecureTextureException;
import net.minecraft.client.renderer.texture.AbstractTexture;
import net.minecraft.client.renderer.texture.HttpTexture;
import com.google.common.hash.Hashing;
import javax.annotation.Nullable;
import net.minecraft.resources.ResourceLocation;
import com.google.common.collect.Maps;
import net.minecraft.client.Minecraft;
import com.google.common.cache.CacheLoader;
import java.util.concurrent.TimeUnit;
import com.google.common.cache.CacheBuilder;
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
import java.util.Map;
import com.mojang.authlib.GameProfile;
import com.google.common.cache.LoadingCache;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import java.io.File;
import net.minecraft.client.renderer.texture.TextureManager;

public class SkinManager {
    private final TextureManager textureManager;
    private final File skinsDirectory;
    private final MinecraftSessionService sessionService;
    private final LoadingCache<GameProfile, Map<MinecraftProfileTexture.Type, MinecraftProfileTexture>> insecureSkinCache;
    
    public SkinManager(final TextureManager eak, final File file, final MinecraftSessionService minecraftSessionService) {
        this.textureManager = eak;
        this.skinsDirectory = file;
        this.sessionService = minecraftSessionService;
        this.insecureSkinCache = CacheBuilder.newBuilder().expireAfterAccess(15L, TimeUnit.SECONDS).<GameProfile, Map<MinecraftProfileTexture.Type, MinecraftProfileTexture>>build(new CacheLoader<GameProfile, Map<MinecraftProfileTexture.Type, MinecraftProfileTexture>>() {
            @Override
            public Map<MinecraftProfileTexture.Type, MinecraftProfileTexture> load(final GameProfile gameProfile) throws Exception {
                try {
                    return (Map<MinecraftProfileTexture.Type, MinecraftProfileTexture>)Minecraft.getInstance().getMinecraftSessionService().getTextures(gameProfile, false);
                }
                catch (Throwable throwable3) {
                    return Maps.newHashMap();
                }
            }
        });
    }
    
    public ResourceLocation registerTexture(final MinecraftProfileTexture minecraftProfileTexture, final MinecraftProfileTexture.Type type) {
        return this.registerTexture(minecraftProfileTexture, type, null);
    }
    
    public ResourceLocation registerTexture(final MinecraftProfileTexture minecraftProfileTexture, final MinecraftProfileTexture.Type type, @Nullable final SkinTextureCallback a) {
        final String string5 = Hashing.sha1().hashUnencodedChars(minecraftProfileTexture.getHash()).toString();
        final ResourceLocation sm6 = new ResourceLocation("skins/" + string5);
        final AbstractTexture dzw7 = this.textureManager.getTexture(sm6);
        if (dzw7 != null) {
            if (a != null) {
                a.onSkinTextureAvailable(type, sm6, minecraftProfileTexture);
            }
        }
        else {
            final File file8 = new File(this.skinsDirectory, (string5.length() > 2) ? string5.substring(0, 2) : "xx");
            final File file9 = new File(file8, string5);
            final ResourceLocation sm7;
            final HttpTexture dzz10 = new HttpTexture(file9, minecraftProfileTexture.getUrl(), DefaultPlayerSkin.getDefaultSkin(), type == MinecraftProfileTexture.Type.SKIN, () -> {
                if (a != null) {
                    a.onSkinTextureAvailable(type, sm7, minecraftProfileTexture);
                }
                return;
            });
            this.textureManager.register(sm6, dzz10);
        }
        return sm6;
    }
    
    public void registerSkins(final GameProfile gameProfile, final SkinTextureCallback a, final boolean boolean3) {
        final HashMap<Object, Object> map5;
        final Map<K, MinecraftProfileTexture> map6;
        final Runnable runnable5 = () -> {
            map5 = Maps.newHashMap();
            try {
                map5.putAll(this.sessionService.getTextures(gameProfile, boolean3));
            }
            catch (InsecureTextureException ex) {}
            if (map5.isEmpty()) {
                gameProfile.getProperties().clear();
                if (gameProfile.getId().equals(Minecraft.getInstance().getUser().getGameProfile().getId())) {
                    gameProfile.getProperties().putAll((Multimap)Minecraft.getInstance().getProfileProperties());
                    map5.putAll(this.sessionService.getTextures(gameProfile, false));
                }
                else {
                    this.sessionService.fillProfileProperties(gameProfile, boolean3);
                    try {
                        map5.putAll(this.sessionService.getTextures(gameProfile, boolean3));
                    }
                    catch (InsecureTextureException ex2) {}
                }
            }
            Minecraft.getInstance().execute(() -> RenderSystem.recordRenderCall(() -> ImmutableList.<MinecraftProfileTexture.Type>of(MinecraftProfileTexture.Type.SKIN, MinecraftProfileTexture.Type.CAPE).forEach(type -> {
                if (map6.containsKey(type)) {
                    this.registerTexture(map6.get(type), type, a);
                }
            })));
            return;
        };
        Util.backgroundExecutor().execute(runnable5);
    }
    
    public Map<MinecraftProfileTexture.Type, MinecraftProfileTexture> getInsecureSkinInformation(final GameProfile gameProfile) {
        return this.insecureSkinCache.getUnchecked(gameProfile);
    }
    
    public interface SkinTextureCallback {
        void onSkinTextureAvailable(final MinecraftProfileTexture.Type type, final ResourceLocation sm, final MinecraftProfileTexture minecraftProfileTexture);
    }
}
