package com.steering.comm.tools;

import com.google.gson.Gson;
import net.sf.json.JSONObject;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.regex.Matcher;

/**
 * 实体类工具
 * @author Administrator
 */
public class EntityTool {

    /**
     * 用实体类的值替换Sql中定义的 #字段名# 参数。
     * @param sql sql语句
     * @param obj 实体类对象
     * @return 替换后的sql语句。
     */
    public static String fillSqlByEntity(String sql, Object obj) {
        String sql2 = sql;
        Class<?> cls = obj.getClass();
        Field[] fields = cls.getDeclaredFields();
        for (Field field : fields) {
            try {
                String fieldName = getMethodName(field.getName());
                Method m = (Method) obj.getClass().getMethod("get" + fieldName);
                String val = m.invoke(obj) == null ? "" : m.invoke(obj).toString();//
                String sqlFieldName = "#" + getSqlFieldName(fieldName) + "#";
                val = val.replaceAll("'", "''");
                sql2 = sql2.replaceAll(sqlFieldName,
                        Matcher.quoteReplacement(val));
            }
            catch (Exception e) {
                continue;
            }
        }

        return sql2;
    }

    // 比如： StdCode转换为 STD_CODE
    private static String getSqlFieldName(String fieldName) {
        StringBuilder sb = new StringBuilder(fieldName);
        for (int i = 1; i < sb.length(); i++) {
            char ch = sb.charAt(i);
            if (Character.isUpperCase(ch)) {
                sb.insert(i, '_');
                i++;
            }
        }

        return sb.toString().toUpperCase();
    }

    private static String getMethodName(String fildeName) throws Exception {
        byte[] items = fildeName.getBytes();
        items[0] = (byte) ((char) items[0] - 'a' + 'A');
        return new String(items);
    }

    /**
     * 获取实体类集合
     * @param rs 结果集
     * @param cls 实体类的类型
     * @return 实体类集合
     */
    public static <T> ArrayList<T> getEntitysByRs(ResultSet rs, Class<T> cls) {
        ArrayList<T> list = new ArrayList<T>();
        Method[] methods = cls.getMethods();
        HashMap<String, Method> map = new HashMap<String, Method>();

        for (int i = 0; i < methods.length; i++) {
            try {
                Method method = methods[i];
                String methodName = method.getName();
                if (methodName.startsWith("set")) {
                    String entityName = methodName.substring(3,
                            methodName.length());
                    String fieldName = getSqlFieldName(entityName);
                    if (rs.findColumn(fieldName) > 0) {
                        map.put(fieldName, method);
                    }
                }
            }
            catch (Exception e) {
            }
        }

        try {
            while (rs.next()) {
                T obj = cls.newInstance();
                Iterator<Entry<String, Method>> iter = map.entrySet()
                        .iterator();
                while (iter.hasNext()) {
                    Entry<String, Method> entry = iter.next();
                    String key = entry.getKey();
                    Method val = entry.getValue();
                    String strValue = rs.getString(key);
                    strValue = strValue == null ? "" : strValue;
                    val.invoke(obj, strValue);
                }
                list.add(obj);
            }
        }
        catch (Exception e) {
        	//System.out.println(e.toString());
            return list;
        }
        return list;
    }

    /**
     * 通过sql获取实体类集合（不关闭Connection）
     * @param sql
     * @param con
     * @param cls
     * @return
     */
    public static <T> ArrayList<T> getEntitysBySqlNoClsCon(String sql,
            Connection con, Class<T> cls) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = con.prepareStatement(sql);
            rs = ps.executeQuery();
            return getEntitysByRs(rs, cls);
        }
        catch (SQLException e) {

        }
        finally {
            if (rs != null) {
                try {
                    rs.close();
                }
                catch (Exception ex) {
                }
            }
            if (ps != null) {
                try {
                    ps.close();
                }
                catch (Exception ex) {
                }
            }
        }
        return null;
    }
    
    /**
     * 通过sql获取实体类（不关闭Connection）
     * @param sql
     * @param con
     * @param cls
     * @return
     */
    public static <T> T getEntityBySqlNoClsCon(String sql,
            Connection con, Class<T> cls) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = con.prepareStatement(sql);
            rs = ps.executeQuery();
            return getEntityByRs(rs, cls);
        }
        catch (SQLException e) {
        	e.printStackTrace();
        }
        finally {
            if (rs != null) {
                try {
                    rs.close();
                }
                catch (Exception ex) {
                }
            }
            if (ps != null) {
                try {
                    ps.close();
                }
                catch (Exception ex) {
                }
            }
        }
        return null;
    }

    /**
     * 通过sql获取实体类集合（关闭Connection）
     * @param sql
     * @param con
     * @param cls
     * @return
     */
    public static <T> ArrayList<T> getEntitysBySql(String sql, Connection con,
            Class<T> cls) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = con.prepareStatement(sql);
            rs = ps.executeQuery();
            return getEntitysByRs(rs, cls);
        }
        catch (SQLException e) {

        }
        finally {
            if (rs != null) {
                try {
                    rs.close();
                }
                catch (Exception ex) {
                }
            }
            if (ps != null) {
                try {
                    ps.close();
                }
                catch (Exception ex) {
                }
            }
            if (con != null) {
                try {
                    con.close();
                }
                catch (Exception ex) {
                }
            }
        }
        return null;
    }
    
    /**
     * 通过sql获取实体类（关闭Connection）
     * @param sql
     * @param con
     * @param cls
     * @return
     */
    public static <T> T getEntityBySql(String sql, Connection con,
            Class<T> cls) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = con.prepareStatement(sql);
            rs = ps.executeQuery();
            return getEntityByRs(rs, cls);
        }
        catch (SQLException e) {

        }
        finally {
            if (rs != null) {
                try {
                    rs.close();
                }
                catch (Exception ex) {
                }
            }
            if (ps != null) {
                try {
                    ps.close();
                }
                catch (Exception ex) {
                }
            }
            if (con != null) {
                try {
                    con.close();
                }
                catch (Exception ex) {
                }
            }
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    public static <T> T getEntityByJSONStr(String strJSON, Class<T> cls) {
        JSONObject obj = JSONObject.fromObject(strJSON);
        T tEntity = (T) JSONObject.toBean(obj, cls);

        return tEntity;
    }
    
    /**
     * 通过谷歌的Gson转换实体类
     * @param json
     * @param cls
     * @return
     */
    public static<T> T getEntityByGson(String json, Class<T> cls){
    	Gson gson = new Gson();
    	return gson.fromJson(json, cls);
    }
    
    /**
     * 通过谷歌的Gson转换实体类
     * @param json
     * @param cls
     * @return
     */
    public static<T> ArrayList<T> getEntitysByGson(String json, Type listType){
    	Gson gson = new Gson();
    	return gson.fromJson(json, listType);
    }
    
    
    /**
     * 通过谷歌的Gson转换为字符串
     * @param src
     * @return
     */
    public static String getGsonByEntity(Object src){
    	Gson gson = new Gson();
    	return gson.toJson(src);
    }

    /**
     * 通过结果集RS获取单个实体类
     * @param rs
     * @param cls
     * @return
     */
    public static <T> T getEntityByRs(ResultSet rs, Class<T> cls) {
        T list = null;
        Method[] methods = cls.getMethods();
        HashMap<String, Method> map = new HashMap<String, Method>();

        for (int i = 0; i < methods.length; i++) {
            try {
                Method method = methods[i];
                String methodName = method.getName();
                if (methodName.startsWith("set")) {
                    String entityName = methodName.substring(3,
                            methodName.length());
                    String fieldName = getSqlFieldName(entityName);
                    if (rs.findColumn(fieldName) > 0) {
                        map.put(fieldName, method);
                    }
                }
            }
            catch (Exception e) {
            }
        }

        try {
            if (rs.next()) {
                T obj = cls.newInstance();
                Iterator<Entry<String, Method>> iter = map.entrySet()
                        .iterator();
                while (iter.hasNext()) {
                    Entry<String, Method> entry = iter.next();
                    String key = entry.getKey();
                    Method val = entry.getValue();
                    String strValue = rs.getString(key);
                    strValue = strValue == null ? "" : strValue;
                    val.invoke(obj, strValue);
                }
                list = obj;
            }
        }
        catch (Exception e) {
            return list;
        }
        return list;
    }
    
    /**
     * 获取实体类指定方法的值。
     * @param obj
     * @param methodName
     * @return
     */
    @SuppressWarnings("all")
    public static String getValue(Object obj, String fieldName){
    	try {
			Method method = obj.getClass().getMethod("get" + fieldName, new Class[0]);
			
			return method.invoke(obj, new Object[0]).toString();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	
    	return "";
    }
    
    /**
     * 复制数据
     * @param srcObj
     * @param desObj
     */
    public static <T> T copy(Object srcObj, Class<T> cls){
    	return getEntityByGson(getGsonByEntity(srcObj), cls);
    }
}
