package com.pictc.common.mybatis;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;


@MappedTypes({Object.class})
@MappedJdbcTypes(JdbcType.VARCHAR)
public class JsonTypeHandler<T> extends AbstractJsonTypeHandler<Object> {
	
	private boolean list;
	
	private Class<?> entityClass;
	
	public JsonTypeHandler(Class<?> type) {
        list = isList(type);
    }

    public JsonTypeHandler(Class<?> type, Field field) {
		list = isList(type);
		try {
			entityClass = getFeildFanClass(field, 0);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	@Override
    public Object parse(String json) {
    	if(list) {
    		return JSON.parseArray(json,entityClass);
    	}
    	return JSON.parseObject(json,entityClass);
    }

    @Override
    public String toJson(Object obj) {
    	if(obj==null) return null;
        return JSON.toJSONString(obj, SerializerFeature.WriteMapNullValue,
            SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty);
    }
    
	/**
	 * 是否是list集合
	 * */
    private boolean isList(Class<?> klass) {
		return hashClass(klass, List.class);
	}
    
	/**
	 * klass是否实现了face类或接口
	 * @author tanuki
	 * @param klass 要判断的类型
	 * @param face  指定的类型
	 * */
	private boolean hashClass(Class<?> klass, Class<?> face) {
		if (klass.equals(face)) {
			return true;
		} else {
			if (Object.class.equals(klass)) {
				return false;
			}
			Class<?>[] cls = klass.getInterfaces();
			for (int i = 0; i < cls.length; i++) {
				if (hashClass(cls[i], face)) {
					return true;
				}
			}
			if (!klass.isInterface()) {
				if (hashClass(klass.getSuperclass(), face)) {
					return true;
				}
			}
		}
		return false;
	}
	
	private Class<?> getFeildFanClass(Field field,int index) throws ClassNotFoundException {
		return getClass(getFeildFan(field, index));
	}
	
	/**
	 * Type 类型转 class
	 * */
	private Class<?>  getClass(Type type) throws ClassNotFoundException{
		String cStr=type.toString();
		if(cStr.indexOf("class ")==0){
			return Class.forName(cStr.substring(6, cStr.length()));
		}else if(cStr.indexOf("interface ")==0){
			return Class.forName(cStr.substring(10, cStr.length()));
		}else{
			if(cStr.indexOf("<")!=-1){
				return Class.forName(cStr.substring(0, cStr.indexOf("<")));
			}
			return Class.forName(cStr.substring(0, cStr.length()));
		}
	}
    
	private Type getFeildFan(Field field,int index) {
		Type type = field.getGenericType();
		if(type instanceof ParameterizedType){
			return ((ParameterizedType)type).getActualTypeArguments()[index];
		}
		return field.getType();
	}

}
