package me.nithanim.gw2api.v2.util.gson.items;

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import me.nithanim.gw2api.v2.api.items.Details;
import me.nithanim.gw2api.v2.api.items.ItemInfo;
import me.nithanim.gw2api.v2.api.items.ItemType;

public class ItemInfoJsonDeserializer implements JsonDeserializer<ItemInfo> {
    private static final Map<String, Field> fields = new HashMap<>();
    
    static {
        Field[] fs = ItemInfo.class.getDeclaredFields();
        for(Field f : fs) {
            f.setAccessible(true);
            String name = toJsonName(f.getName());
            fields.put(name, f);
        }
    }

    private static String toJsonName(String name) {
        StringBuilder sb = new StringBuilder();
        sb.append(name);
        for(int i = 0; i < sb.length(); i++) {
            char c = sb.charAt(i);
            if(Character.isUpperCase(c)) {
                sb.setCharAt(i, '_');
                sb.insert(i+1, Character.toLowerCase(c));
            }
        }
        return sb.toString();
    }
    
    
    @Override
    public ItemInfo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonObject root = json.getAsJsonObject();
        ItemInfo ii = new ItemInfo();
        for(Map.Entry<String, JsonElement> t : root.entrySet()) {
            if(!t.getKey().equals("details")) {
                Field field = fields.get(t.getKey());
                if(field != null) {
                    Object value = context.deserialize(t.getValue(), field.getType());
                    try {
                        field.set(ii, value);
                    } catch (IllegalAccessException ex) {
                        throw new RuntimeException("Unexpected difficulties while deserializing ItemInfo!", ex);
                    }
                }
            }
        }
        
        ItemType type = ii.getType();
        Class<? extends Details> detailClass = type.getDetailsClass();
        if(detailClass != null) {
            Object details = context.deserialize(root.get("details"), detailClass);
            try {
                Field field = fields.get("details");
                field.set(ii, details);
            } catch (IllegalAccessException ex) {
                throw new RuntimeException("Unable to set Details in ItemInfo while deserializing!", ex);
            }
        }
        return ii;
    }
}

@@ -595,23 +595,16 @@
 private 
-static 
 final Ma
@@ -650,597 +650,206 @@
 ();%0A
-    
 %0A    
-static %7B%0A        Field%5B%5D fs = ItemInfo.class.getDeclaredFields();%0A        for(Field f : fs) %7B%0A            f.setAccessible(true);%0A            String name = toJsonName(f.getName());%0A            fields.put(name, f);%0A   
+public ItemInfoJsonDeserializer() %7B%0A        Class%3C?%3E clazz = ItemInfo.class;%0A        while (clazz != null) %7B%0A
      
-%7D%0A
     
-%7D%0A%0A    private static String toJsonName(String name) %7B%0A        StringBuilder sb = new StringBuilder();%0A        sb.append(name);%0A        for(int i = 0; i %3C sb.length(); i++) %7B%0A            char c = sb.charAt(i);%0A            if(Character.isUpperCase(c)) %7B%0A                sb.setCharAt(i, '_');%0A                sb.insert(i+1, Character.toLowerCase(c));%0A    
+   registerAllFieldsFor(clazz);%0A            clazz = clazz.getSuperclass();%0A
     
@@ -858,63 +858,14 @@
   %7D%0A
-    
     %7D%0A
-        return sb.toString();%0A    %7D%0A    %0A    
 %0A   
@@ -1102,16 +1102,17 @@
      for
+ 
 (Map.Ent
@@ -1172,16 +1172,17 @@
       if
+ 
 (!t.getK
@@ -1279,16 +1279,17 @@
       if
+ 
 (field !
@@ -1692,24 +1692,16 @@
       %7D%0A
-        
 %0A       
@@ -1812,16 +1812,17 @@
       if
+ 
 (detailC
@@ -2236,11 +2236,987 @@
 i;%0A    %7D
+%0A%0A    private void registerAllFieldsFor(Class clazz) %7B%0A        Field%5B%5D fs = clazz.getDeclaredFields();%0A        for (Field f : fs) %7B%0A            f.setAccessible(true);%0A            String name = toJsonName(f.getName());%0A%0A            Field prev = fields.put(name, f);%0A            if (prev != null) %7B%0A                throw new IllegalStateException(%0A                    %22Another field with the name %22%0A                    + f.getName() + %22 was already found in %22%0A                    + prev.getDeclaringClass() + %22 before reading %22 + clazz);%0A            %7D%0A        %7D%0A    %7D%0A%0A    private static String toJsonName(String name) %7B%0A        StringBuilder sb = new StringBuilder();%0A        sb.append(name);%0A        for (int i = 0; i %3C sb.length(); i++) %7B%0A            char c = sb.charAt(i);%0A            if (Character.isUpperCase(c)) %7B%0A                sb.setCharAt(i, '_');%0A                sb.insert(i + 1, Character.toLowerCase(c));%0A            %7D%0A        %7D%0A        return sb.toString();%0A    %7D
 %0A%7D%0A

Fix id in ItemInfo always 0