/*
 * Copyright 1999-2011 Alibaba Group.
 *  
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *      http://www.apache.org/licenses/LICENSE-2.0
 *  
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.dubbo.common.utils;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

/**
 * PojoUtils. Travel object deeply, and convert complex type to simple type.
 * <p>
 * Type below will be remained: 
 * <ul>
 * <li> Primitive Type, also include <b>String</b>, <b>Number</b>(Integer, Long), <b>Date</b>
 * <li> Array of Primitive Type
 * <li> Collection, eg: List, Map, Set etc.
 * </ul>
 * <p>
 * Other type will be covert to a map which contains the attributes and value pair of object.
 * 
 * @author william.liangf
 * @author ding.lid
 */
public class PojoUtils {

    public static Object[] generalize(Object[] objs) {
        Object[] dests = new Object[objs.length];
        for (int i = 0; i < objs.length; i ++) {
            dests[i] = generalize(objs[i]);
        }
        return dests;
    }

    public static Object[] realize(Object[] objs, Class<?>[] types) {
        if (objs.length != types.length)
            throw new IllegalArgumentException("args.length != types.length");
        Object[] dests = new Object[objs.length];
        for (int i = 0; i < objs.length; i ++) {
            dests[i] = realize(objs[i], types[i]);
        }
        return dests;
    }

    public static Object[] realize(Object[] objs, Class<?>[] types, Type[] gtypes) {
        if (objs.length != types.length
                || objs.length != gtypes.length)
            throw new IllegalArgumentException("args.length != types.length");
        Object[] dests = new Object[objs.length];
        for (int i = 0; i < objs.length; i ++) {
            dests[i] = realize(objs[i], types[i], gtypes[i]);
        }
        return dests;
    }

    public static Object generalize(Object pojo) {
        return generalize(pojo, new HashMap<Integer, Object>());
    }

    @SuppressWarnings("unchecked")
    private static Object generalize(Object pojo, Map<Integer, Object> history) {
        if (pojo == null) {
            return null;
        }
        
        if (pojo instanceof Enum<?>) {
            return ((Enum<?>)pojo).name();
        }
        if (pojo.getClass().isArray() 
        		&& Enum.class.isAssignableFrom(
        				pojo.getClass().getComponentType())) {
        	int len = Array.getLength(pojo);
        	String[] values = new String[len];
        	for (int i = 0; i < len; i ++) {
        		values[i] = ((Enum<?>)Array.get(pojo, i)).name();
        	}
            return values;
        }
        
        if (ReflectUtils.isPrimitives(pojo.getClass())) {
            return pojo;
        }
        
        Integer id = System.identityHashCode(pojo);
        if (history.containsKey(id)) {
            return history.get(id);
        }
        history.put(id, pojo);
        
        if (pojo.getClass().isArray()) {
            int len = Array.getLength(pojo);
            Object[] dest = new Object[len];
            for (int i = 0; i < len; i ++) {
                Object obj = Array.get(pojo, i);
                dest[i] = generalize(obj, history);
            }
            return dest;
        }
        if (pojo instanceof Collection<?>) {
            Collection<Object> src = (Collection<Object>)pojo;
            int len = src.size();
            Collection<Object> dest = (pojo instanceof List<?>) ? new ArrayList<Object>(len) : new HashSet<Object>(len);
            for (Object obj : src) {
                dest.add(generalize(obj, history));
            }
            return dest;
        }
        if (pojo instanceof Map<?, ?>) {
            Map<Object, Object> src = (Map<Object, Object>)pojo;
            Map<Object, Object> tmp = new HashMap<Object, Object>(src.size());
            tmp.putAll(src);
            for (Map.Entry<Object, Object> obj : tmp.entrySet()) {
            	src.put(generalize(obj.getKey(), history), generalize(obj.getValue(), history));
            }
            return src;
        }
        Map<String, Object> map = new HashMap<String, Object>();
        history.put(id, map);
        map.put("class", pojo.getClass().getName());
        for (Method method : pojo.getClass().getMethods()) {
            if (Modifier.isPublic(method.getModifiers())
                    && method.getDeclaringClass() != Object.class
                    && method.getParameterTypes().length == 0) {
                String name = method.getName();
                try {
                    if (name.startsWith("get")) {
                        map.put(name.substring(3, 4).toLowerCase() + name.substring(4), generalize(method
                                .invoke(pojo, new Object[0]), history));
                    } else if (name.startsWith("is")) {
                        map.put(name.substring(2, 3).toLowerCase() + name.substring(3), generalize(method
                                .invoke(pojo, new Object[0]), history));
                    }
                } catch (Exception e) {
                    throw new RuntimeException(e.getMessage(), e);
                }
            }
        }
        return map;
    }
    
    public static Object realize(Object pojo, Class<?> type) {
        return realize(pojo, type, new HashMap<Integer, Object>());
    }
    
    public static Object realize(Object pojo, Class<?> type, Type genericType) {
        return realize(pojo, type, genericType, new HashMap<Integer, Object>());
    }
    
    private static class PojoInvocationHandler implements InvocationHandler {
        
        private Map<Object, Object> map;

        public PojoInvocationHandler(Map<Object, Object> map) {
            this.map = map;
        }

        @SuppressWarnings("unchecked")
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if (method.getDeclaringClass() == Object.class) {
                return method.invoke(map, args);
            }
            String methodName = method.getName();
            Object value = null;
            if (methodName.length() > 3 && methodName.startsWith("get")) {
                value = map.get(methodName.substring(3, 4).toLowerCase() + methodName.substring(4));
            } else if (methodName.length() > 2 && methodName.startsWith("is")) {
                value = map.get(methodName.substring(2, 3).toLowerCase() + methodName.substring(3));
            } else {
                value = map.get(methodName.substring(0, 1).toLowerCase() + methodName.substring(1));
            }
            if (value instanceof Map<?,?> && ! Map.class.isAssignableFrom(method.getReturnType())) {
                value = realize((Map<String, Object>)value, method.getReturnType(), new HashMap<Integer, Object>());
            }
            return value;
        }
    }
    
    @SuppressWarnings("unchecked")
	private static Collection<Object> createCollection(Class<?> type, int len) {
    	if (type.isAssignableFrom(ArrayList.class)) {
    		return  new ArrayList<Object>(len);
    	}
    	if (type.isAssignableFrom(HashSet.class)) {
    		return new HashSet<Object>(len);
    	}
    	if (! type.isInterface() && ! Modifier.isAbstract(type.getModifiers())) {
    		try {
				return (Collection<Object>) type.newInstance();
			} catch (Exception e) {
				// ignore
			}
    	}
    	return new ArrayList<Object>();
    }

    private static Object realize(Object pojo, Class<?> type, final Map<Integer, Object> history) {
        return realize(pojo, type, null , history);
    }
    
    @SuppressWarnings({ "unchecked", "rawtypes" })
    private static Object realize(Object pojo, Class<?> type, Type genericType, final Map<Integer, Object> history) {
        if (pojo == null) {
            return null;
        }
        
        if (type != null && type.isEnum() 
        		&& pojo.getClass() == String.class) {
    		return Enum.valueOf((Class<Enum>)type, (String)pojo);
    	}
        
        if (ReflectUtils.isPrimitives(pojo.getClass()) 
        		&& ! (type != null && type.isArray() 
        				&& type.getComponentType().isEnum()
        				&& pojo.getClass() == String[].class)) {
            return CompatibleTypeUtils.compatibleTypeConvert(pojo, type);
        }
        
        Integer id = System.identityHashCode(pojo);
        if (history.containsKey(id)) {
            return history.get(id);
        }
        history.put(id, pojo);
        
        if (pojo.getClass().isArray()) {
        	if (Collection.class.isAssignableFrom(type)) {
        		Class<?> ctype = pojo.getClass().getComponentType();
	            int len = Array.getLength(pojo);
        		Collection dest = createCollection(type, len);
        		for (int i = 0; i < len; i ++) {
	                Object obj = Array.get(pojo, i);
	                Object value = realize(obj, ctype, history);
	                dest.add(value);
	            }
	            return dest;
        	} else {
	        	Class<?> ctype = (type != null && type.isArray() ? type.getComponentType() : pojo.getClass().getComponentType());
	            int len = Array.getLength(pojo);
	            Object dest = Array.newInstance(ctype, len);
	            for (int i = 0; i < len; i ++) {
	                Object obj = Array.get(pojo, i);
	                Object value = realize(obj, ctype, history);
	                Array.set(dest, i, value);
	            }
	            return dest;
            }
        }
        
        if (pojo instanceof Collection<?>) {
        	if (type.isArray()) {
        		Class<?> ctype = type.getComponentType();
                Collection<Object> src = (Collection<Object>)pojo;
                int len = src.size();
                Object dest = Array.newInstance(ctype, len);
                int i = 0;
                for (Object obj : src) {
                    Object value = realize(obj, ctype, history);
                    Array.set(dest, i, value);
                    i ++;
                }
                return dest;
        	} else {
        		Collection<Object> src = (Collection<Object>)pojo;
                int len = src.size();
                Collection<Object> dest = createCollection(type, len);
                for (Object obj : src) {
                    Type keyType = getGenericClassByIndex(genericType, 0);
                    Class<?> keyClazz = obj.getClass() ;
                    if ( keyType instanceof Class){
                      keyClazz = (Class<?>)keyType;
                    } 
                	Object value = realize(obj, keyClazz, keyType, history);
                    dest.add(value);
                }
                return dest;
        	}
        }
        
        if (pojo instanceof Map<?, ?> && type != null) {
        	Object className = ((Map<Object, Object>)pojo).get("class");
            if (className instanceof String && ! Map.class.isAssignableFrom(type)) {
                try {
                    type = ClassHelper.forName((String)className);
                } catch (ClassNotFoundException e) {
                    // ignore
                }
            }
            Map<Object, Object> map ;
            // 返回值类型不是方法签名类型的子集 并且 不是接口类型
            if (! type.isInterface()
                    && ! type.isAssignableFrom(pojo.getClass())){
                try {
                    map = (Map<Object,Object>)type.newInstance();
                } catch (Exception e) {
                    //ignore error
                    map = (Map<Object, Object>)pojo;
                }
            }else {
                map = (Map<Object, Object>)pojo;
            }
            
            if (Map.class.isAssignableFrom(type) || type == Object.class) {
            	final Map<Object, Object> tmp = new HashMap<Object, Object>(map.size());
            	tmp.putAll(map);
            	for (Map.Entry<Object, Object> entry : tmp.entrySet()) {
            	    Type keyType = getGenericClassByIndex(genericType, 0);
            	    Type valueType = getGenericClassByIndex(genericType, 1);
            	    Class<?> keyClazz;
            	    if ( keyType instanceof Class){
            	        keyClazz = (Class<?>)keyType;
            	    } else {
            	        keyClazz = entry.getKey() == null ? null : entry.getKey().getClass();
            	    }
            	    Class<?> valueClazz;
                    if ( valueType instanceof Class){
                        valueClazz = (Class<?>)valueType;
                    } else {
                        valueClazz = entry.getValue() == null ? null : entry.getValue().getClass() ;
                    }
            	    
            	    Object key = keyClazz == null ? entry.getKey() : realize(entry.getKey(), keyClazz, keyType, history);
            	    Object value = valueClazz == null ? entry.getValue() : realize(entry.getValue(), valueClazz, valueType, history);
            		map.put(key, value);
            	}
        		return map;
        	} else if (type.isInterface()) {
        	    Object dest = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[]{type}, new PojoInvocationHandler(map));
                history.put(id, dest);
                return dest;
            } else {
                Object dest = newInstance(type);
                history.put(id, dest);
                for (Map.Entry<Object, Object> entry : map.entrySet()) {
                	Object key = entry.getKey();
                	if (key instanceof String) {
	                    String name = (String) key;
	                    Object value = entry.getValue();
	                    if (value != null) {
	                        Method method = getSetterMethod(dest.getClass(), name, value.getClass());
	                        if (method != null) {
	                            if (! method.isAccessible())
	                                method.setAccessible(true);
	                            Type ptype = method.getGenericParameterTypes()[0];
	                            value = realize(value, method.getParameterTypes()[0], ptype, history);
	                            try {
	                                method.invoke(dest, value);
	                            } catch (Exception e) {
	                                throw new RuntimeException("Failed to set pojo " + dest.getClass().getSimpleName() + " property " + name + " value " + value + ", cause: " + e.getMessage(), e);
	                            }
	                        }
	                    }
                	}
                }
                if (dest instanceof Throwable) {
                    Object message = map.get("message");
                    if (message instanceof String) {
                        try {
                            Field filed = Throwable.class.getDeclaredField("detailMessage");
                            if(! filed.isAccessible()) {
                                filed.setAccessible(true);
                            }
                            filed.set(dest, (String) message);
                        } catch (Exception e) {
                        }
                    }
                }
                return dest;
            }
        }
        return pojo;
    }
    
    /**
     * 获取范型的类型 
     * @param genericType
     * @param index
     * @return List<Person>  返回Person.class ,Map<String,Person> index=0 返回String.class index=1 返回Person.class
     */
    private static Type getGenericClassByIndex(Type genericType, int index){
        Type clazz = null ;
        //范型参数转换 
        if (genericType instanceof ParameterizedType){
            ParameterizedType t = (ParameterizedType)genericType;
            Type[] types = t.getActualTypeArguments();
            clazz = types[index];
        }
        return clazz;
    }
    
    private static Object newInstance(Class<?> cls) {
        try {
            return cls.newInstance();
        } catch (Throwable t) {
            try {
                Constructor<?>[] constructors = cls.getConstructors();
                if (constructors != null && constructors.length > 0) {
                    throw new RuntimeException("Illegal constructor: " + cls.getName());
                }
                Constructor<?> constructor = constructors[0];
                if (constructor.getParameterTypes().length > 0) {
                    for (Constructor<?> c : constructors) {
                        if (c.getParameterTypes().length < 
                                constructor.getParameterTypes().length) {
                            constructor = c;
                            if (constructor.getParameterTypes().length == 0) {
                                break;
                            }
                        }
                    }
                }
                return constructor.newInstance(new Object[constructor.getParameterTypes().length]);
            } catch (InstantiationException e) {
                throw new RuntimeException(e.getMessage(), e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e.getMessage(), e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e.getMessage(), e);
            }
        }
    }

    private static Method getSetterMethod(Class<?> cls, String property, Class<?> valueCls) {
        String name = "set" + property.substring(0, 1).toUpperCase() + property.substring(1);
        try {
            return cls.getMethod(name, valueCls);
        } catch (NoSuchMethodException e) {
            for (Method method : cls.getMethods()) {
                if (Modifier.isPublic(method.getModifiers())
                        && method.getDeclaringClass() != Object.class
                        && method.getParameterTypes().length == 1 
                        && method.getName().equals(name)) {
                    return method;
                }
            }
        }
        return null;
    }
    
    public static boolean isPojo(Class<?> cls) {
        return ! ReflectUtils.isPrimitives(cls)
                && ! Collection.class.isAssignableFrom(cls) 
                && ! Map.class.isAssignableFrom(cls);
    }

}