package cn.citycraft.GsonAgent.nms.reflect;

import java.lang.reflect.Type;

import cn.citycraft.GsonAgent.api.reflect.TypeTokenAbstract;
import cn.citycraft.GsonAgent.api.utils.Utils;
import net.minecraft.util.com.google.gson.reflect.TypeToken;

@SuppressWarnings({ "unchecked", "rawtypes" })
public class TypeTokenHandle<T> implements cn.citycraft.GsonAgent.api.reflect.TypeTokenAbstract<T> {

	private TypeToken<T> handle;

	public TypeTokenHandle() {
		try {
			handle = new TypeToken<T>() {
			};
		} catch (final Exception e) {
			throw new RuntimeException(e);
		}
	}

	public TypeTokenHandle(final Type type) {
		try {
			handle = Utils.newInstance(TypeToken.class, Type.class, type);
		} catch (final Exception e) {
			throw new RuntimeException(e);
		}
	}

	protected TypeTokenHandle(final TypeToken<T> handle) {
		this.handle = handle;
	}

	public static <T> TypeTokenAbstract<T> get(final Class<T> type) {
		return new TypeTokenHandle(TypeToken.get(type));
	}

	public static TypeTokenAbstract<?> get(final Type type) {
		return new TypeTokenHandle(TypeToken.get(type));
	}

	@Override
	public TypeToken<T> getHandle() {
		return this.handle;
	}

	@Override
	public Class<? super T> getRawType() {
		return getHandle().getRawType();
	}

	@Override
	public Type getType() {
		return getHandle().getType();
	}

	@Override
	public boolean isAssignableFrom(final Class<?> cls) {
		return getHandle().isAssignableFrom(cls);
	}

	@Override
	public boolean isAssignableFrom(final cn.citycraft.GsonAgent.api.reflect.TypeToken<?> token) {
		return getHandle().isAssignableFrom((TypeToken<?>) token.getHandle());
	}

	@Override
	public boolean isAssignableFrom(final Type from) {
		return getHandle().isAssignableFrom(from);
	}

}
