// 
// Decompiled by Procyon v0.6.0
// 

package com.google.gson.internal.bind;

import com.google.gson.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.annotations.SerializedName;
import java.lang.reflect.AccessibleObject;
import java.util.Arrays;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.TypeAdapter;

class EnumTypeAdapter<T extends Enum<T>> extends TypeAdapter<T>
{
    static final TypeAdapterFactory FACTORY;
    private final Map<String, T> nameToConstant;
    private final Map<String, T> stringToConstant;
    private final Map<T, String> constantToName;
    
    private EnumTypeAdapter(final Class<T> classOfT) {
        this.nameToConstant = new HashMap<String, T>();
        this.stringToConstant = new HashMap<String, T>();
        this.constantToName = new HashMap<T, String>();
        try {
            Field[] fields = classOfT.getDeclaredFields();
            int constantCount = 0;
            for (final Field f : fields) {
                if (f.isEnumConstant()) {
                    fields[constantCount++] = f;
                }
            }
            fields = Arrays.copyOf(fields, constantCount);
            AccessibleObject.setAccessible(fields, true);
            for (final Field constantField : fields) {
                final T constant = (T)constantField.get(null);
                String name = constant.name();
                final String toStringVal = constant.toString();
                final SerializedName annotation = constantField.getAnnotation(SerializedName.class);
                if (annotation != null) {
                    name = annotation.value();
                    for (final String alternate : annotation.alternate()) {
                        this.nameToConstant.put(alternate, constant);
                    }
                }
                this.nameToConstant.put(name, constant);
                this.stringToConstant.put(toStringVal, constant);
                this.constantToName.put(constant, name);
            }
        }
        catch (final IllegalAccessException e) {
            throw new AssertionError((Object)e);
        }
    }
    
    @Override
    public T read(final JsonReader in) throws IOException {
        if (in.peek() == JsonToken.NULL) {
            in.nextNull();
            return null;
        }
        final String key = in.nextString();
        final T constant = this.nameToConstant.get(key);
        return (constant == null) ? this.stringToConstant.get(key) : constant;
    }
    
    @Override
    public void write(final JsonWriter out, final T value) throws IOException {
        out.value((value == null) ? null : this.constantToName.get(value));
    }
    
    static {
        FACTORY = new TypeAdapterFactory() {
            @Override
            public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) {
                Class<? super T> rawType = typeToken.getRawType();
                if (!Enum.class.isAssignableFrom(rawType) || rawType == Enum.class) {
                    return null;
                }
                if (!rawType.isEnum()) {
                    rawType = rawType.getSuperclass();
                }
                final TypeAdapter<T> adapter = new EnumTypeAdapter<T>(rawType, null);
                return adapter;
            }
        };
    }
}
