package com.pictc.converts;

import java.util.HashMap;
import java.util.Map;

import com.pictc.converts.date.DateHandler;
import com.pictc.converts.date.LocalDateHandler;
import com.pictc.converts.date.LocalDateTimeHandler;
import com.pictc.converts.date.LocalTimeHandler;
import com.pictc.converts.date.TimeHandler;
import com.pictc.converts.date.TimestampHandler;
import com.pictc.converts.primitive.BigDecimalHandler;
import com.pictc.converts.primitive.BigIntegerHandler;
import com.pictc.converts.primitive.BooleanHandler;
import com.pictc.converts.primitive.ByteHandler;
import com.pictc.converts.primitive.CharacterHandler;
import com.pictc.converts.primitive.DoubleHandler;
import com.pictc.converts.primitive.EnumHandler;
import com.pictc.converts.primitive.FloatHandler;
import com.pictc.converts.primitive.IntegerHandler;
import com.pictc.converts.primitive.LongHandler;
import com.pictc.converts.primitive.ShortHandler;
import com.pictc.converts.primitive.StringHandler;
import com.pictc.utils.BeanUtils;
import com.pictc.utils.ClassUtils;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ConverUtil {

    private static Map<Class<?>, SuperHandler> handlers = new HashMap<Class<?>,SuperHandler>();
    
    static {
        Class<?>[] hcls = new Class<?>[] { DateHandler.class,TimestampHandler.class,TimeHandler.class,
        						 LocalDateTimeHandler.class,LocalDateHandler.class,LocalTimeHandler.class,
                                 BooleanHandler.class, ByteHandler.class,
                                 DoubleHandler.class, FloatHandler.class,
                                IntegerHandler.class, LongHandler.class, ShortHandler.class,
                                StringHandler.class,CharacterHandler.class,
                                BigIntegerHandler.class,BigDecimalHandler.class };
        for (int i = 0; i < hcls.length; i++) {
            try {
            	SuperHandler handler = BeanUtils.newInstance(hcls[i]);
                Class<?>[] classes = handler.getConverts();
                for (int j = 0; j < classes.length; j++) {
                    handlers.put(classes[j], handler);
                }
            } catch (Exception e) {
            	log.error("类型转换器初始化异常",e);
            }
        }
    }


    public static void register(Class<?> cls) {
        if (handlers.containsKey(cls)) {
            return;
        }
    	if(cls.isEnum()) {
    		handlers.put(cls, new EnumHandler(cls));
    		return;
    	}
        if (!ClassUtils.hashClass(cls, SuperHandler.class)) {
            return;
        }
        TypeHandler<?> handler;
        try {
            handler = BeanUtils.newInstance(cls);
            handlers.put(cls, handler);
        } catch (Exception e) {
            log.error("注册类型转换器异常",e);
        }
    }


    @SuppressWarnings("unchecked")
    public static <T> TypeHandler<T> geTypeHandler(Class<T> cls) {
        if (!handlers.containsKey(cls)) {
            register(cls);
        }
        return (TypeHandler<T>) handlers.get(cls);
    }
    
    //字符串
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static Object toJsonValue(Class<?> klass,Object val){
		TypeHandler handler = geTypeHandler(klass);
    	return handler!=null?handler.convert(val):val;
    }
    
    //字符串
    @SuppressWarnings("unchecked")
	public static <T>T jsonToValue(Class<T> klass,Object val){
    	TypeHandler<T> handler = geTypeHandler(klass);
    	return handler!=null?handler.valueToObject(val):(T) val;
    }


}


