package com.steering.common;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import net.sf.json.JSONObject;

/**
 * 实体类工具
 * 
 * @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) {
			if (field.getGenericType().toString()
					.equals("class java.lang.String")) {
				try {
					String fieldName = getMethodName(field.getName());
					Method m = obj.getClass().getMethod(
							"get" + fieldName);
					String val = (String) m.invoke(obj);//
					val = val == null ? "" : val;
					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();
		try {
			while (rs.next()) {
				T obj = cls.newInstance();
				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);
							String val = rs.getString(fieldName) == null ? "" : rs.getString(fieldName);
							method.invoke(obj, val);
						}
					} catch (Exception e) {
					}
				}
				list.add(obj);
			}
		} catch (Exception e) {
			return list;
		}
		return list;
	}
	
	/**
     * 通过结果集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;
    }
	
	/**
	 * 通过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> 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;
	}
	 /**
     * 时间增加秒
     * @param beginTime
     * @param second
     * @return
     */
    public static Date dateAddSecond(Date beginTime, int second) {
        Calendar rightNow = Calendar.getInstance();
        rightNow.setTime(beginTime);
        rightNow.add(Calendar.SECOND, second);
        Date dt = rightNow.getTime();
        return dt;
    }

    /**
     * 时间计算
     * @param beginTime 开始时间
     * @param useMinute 用时(分)
     * @return String 结束时间
     * @throws ParseException
     */
    public static String addTime(String beginTime, String useMinute)
            throws ParseException {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        int useSecond = (int) Double.parseDouble(useMinute) * 60;
        String endTime = df
                .format(dateAddSecond(df.parse(beginTime), useSecond));
        return endTime;
    }

    /**
     * 时间自动调整
     * @param con
     * @param gxProSeq
     * @param plineCode
     * @param planTimeE
     * @param processCode
     * @throws SQLException
     * @throws ParseException
     */
    public static void timeIncrease(Connection con, int gxProSeq, String plineCode,
            String planTimeE, String processCode) throws SQLException,
            ParseException {
        String sql = "";
        String updateSql = "";
        if (processCode.equals("B")) {
            sql = "select t.pro_plan_id,t.gx_plan_no,t.plan_usetime from PLN_ORDER_CAST_S t ";
            updateSql = "UPDATE PLN_ORDER_CAST_S T SET T.PLAN_TIME_B = TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS'), T.PLAN_TIME_E = TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS') WHERE T.PRO_PLAN_ID = ? AND T.GX_PLAN_NO = ?";
        }
        else if (processCode.equals("C")) {
            sql = "select t.pro_plan_id,t.gx_plan_no,t.plan_usetime from PLN_ORDER_DZ_S t";
            updateSql = "UPDATE PLN_ORDER_DZ_S T SET T.PLAN_TIME_B = TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS'), T.PLAN_TIME_E = TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS') WHERE T.PRO_PLAN_ID = ? AND T.GX_PLAN_NO = ?";
        }
        else if (processCode.equals("D")) {
            sql = "select t.pro_plan_id,t.gx_plan_no,t.plan_usetime from PLN_ORDER_ZG_S t";
            updateSql = "UPDATE PLN_ORDER_ZG_S T SET T.PLAN_TIME_B = TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS'), T.PLAN_TIME_E = TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS') WHERE T.PRO_PLAN_ID = ? AND T.GX_PLAN_NO = ?";
        }
        else if (processCode.equals("E")) {
            sql = "select t.pro_plan_id,t.gx_plan_no,t.plan_usetime from PLN_ORDER_DBK_S t";
            updateSql = "UPDATE PLN_ORDER_DBK_S T SET T.PLAN_TIME_B = TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS'), T.PLAN_TIME_E = TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS') WHERE T.PRO_PLAN_ID = ? AND T.GX_PLAN_NO = ?";
        }
        else if (processCode.equals("F")) {
            sql = "select t.pro_plan_id,t.gx_plan_no,t.plan_usetime from PLN_ORDER_RCL_S t";
            updateSql = "UPDATE PLN_ORDER_RCL_S T SET T.PLAN_TIME_B = TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS'), T.PLAN_TIME_E = TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS') WHERE T.PRO_PLAN_ID = ? AND T.GX_PLAN_NO = ?";
        }
        else if (processCode.equals("G")) {
            sql = "select t.pro_plan_id,t.gx_plan_no,t.plan_usetime from pln_order_jgx_s t";
            updateSql = "UPDATE PLN_ORDER_JGX_S T SET T.PLAN_TIME_B = TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS'), T.PLAN_TIME_E = TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS') WHERE T.PRO_PLAN_ID = ? AND T.GX_PLAN_NO = ?";
        }
        else {

        }
        sql += " where t.pline_code=? and to_number(t.gx_pro_seq)>to_number(?) order by to_number(t.gx_pro_seq)";
        List<String[]> strArrList = new ArrayList<String[]>();
        PreparedStatement ps = con.prepareStatement(sql);
        ps.setObject(1, plineCode);
        ps.setObject(2, gxProSeq);
        ResultSet rs = ps.executeQuery();
        while (rs.next()) {
            String[] strArr = new String[3];
            strArr[0] = rs.getString("plan_usetime");
            strArr[1] = rs.getString("pro_plan_id");
            strArr[2] = rs.getString("gx_plan_no");
            strArrList.add(strArr);
        }
        rs.close();
        ps.close();
        if (strArrList == null || strArrList.size() == 0) {
            return;
        }
        // 修改时间
        ps = con.prepareStatement(updateSql);
        final int batchSize = 1000;
        int count = 0;
        for (int i = 0; i < strArrList.size(); i++) {
            String[] strArr = strArrList.get(i);
            String planTimeB = planTimeE;
            String planTimeE1 = addTime(planTimeB, strArr[0]);
            planTimeE = planTimeE1;
            ps.setObject(1, planTimeB);
            ps.setObject(2, planTimeE1);
            ps.setObject(3, strArr[1]);
            ps.setObject(4, strArr[2]);
            ps.addBatch();
            if (++count % batchSize == 0) {
                ps.executeBatch();
            }
        }
        ps.executeBatch();
        ps.close();
    }

	@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;
	}

	public static String underlineToCamel(String str) {
		StringBuilder result = new StringBuilder();
		String[] words = str.split("_");
		for (int i = 0; i < words.length; i++) {
			String word = words[i];
			if (i == 0) {
				result.append(word.toLowerCase());
			} else {
				result.append(Character.toUpperCase(word.charAt(0)) + word.substring(1).toLowerCase());
			}
		}
		return result.toString();
	}
}
