package com.thebrokenrail.gestus.skin;

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import org.apache.logging.log4j.LogManager;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Base64;
import java.util.Map;
import java.util.UUID;

final class SkinJSON {
    private static class Response {
        public Property[] properties = null;
    }

    private static class Property {
        public String name = null;
        public String value = null;
    }

    private static class Data {
        public Map<String, Texture> textures;
    }

    private static class Texture {
        public String url = null;
    }

    private static String urlToString(String urlStr) {
        try {
            StringBuilder stringBuilder = new StringBuilder();
            URL url = new URL(urlStr);

            try (BufferedReader in = new BufferedReader(new InputStreamReader(url.openConnection().getInputStream()))) {
                String line;
                while ((line = in.readLine()) != null) {
                    stringBuilder.append(line);
                    stringBuilder.append('\n');
                }
            }

            return stringBuilder.toString();
        } catch (IOException e) {
            return null;
        }
    }

    static void error(String data) {
        LogManager.getLogger("Gestus").error(data);
    }

    private static final String SKIN_TEXTURE_KEY = "SKIN";

    static String get(UUID uuid) {
        String url = String.format("https://sessionserver.mojang.com/session/minecraft/profile/%s", uuid.toString().replace("-", ""));
        String data = urlToString(url);

        if (data != null) {
            try {
                Gson gson = new Gson();
                Response response = gson.fromJson(data, Response.class);

                if (response != null && response.properties != null) {
                    for (Property property : response.properties) {
                        if ("textures".equals(property.name)) {
                            try {
                                String texturesJSON = new String(Base64.getDecoder().decode(property.value));
                                Data textures = gson.fromJson(texturesJSON, Data.class);

                                if (textures.textures.containsKey(SKIN_TEXTURE_KEY)) {
                                    Texture skin = textures.textures.get(SKIN_TEXTURE_KEY);
                                    return skin.url;
                                }

                                break;
                            } catch (JsonSyntaxException e) {
                                error("Unable To Parse Embedded Skin Metadata: " + uuid.toString());
                                return null;
                            }
                        }
                    }
                }

                error("Embedded Skin Metadata Is Invalid: " + uuid.toString());
                return null;
            } catch (JsonSyntaxException e) {
                error("Unable To Parse Skin Metadata: " + uuid);
                return null;
            }
        } else {
            error("Unable To Download Skin Metadata: " + uuid);
            return null;
        }
    }
}
