package com.cftech.core.mybatis.mybatis;


import com.cftech.core.util.Constants;
import com.cftech.core.util.StringUtils;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * Created by lisw on 2016-08-05
 */
public class TableRead {

	/**
	 * 表名到实体对象 时需要去掉的前缀
	 */
	protected String classNamePrefix;

	/**
	 * generateEntity
	 * @param driverName
	 * @param dsUrl
	 * @param dsUserName
	 * @param dsPassword
	 * @param tableName
	 * @return tableBean
	 */
	public TableBean generateEntity(String driverName, String dsUrl, String dsUserName, String dsPassword, String tableName) {
		// flagTimestamp = false;
		TableBean tableBean = new TableBean();
		// 创建连接
		Connection con = null;
		// 查要生成实体类的表
		String sql = "select * from " + tableName + " limit 1";
		PreparedStatement preparedStatement = null;
		try {
			try {
				Class.forName(driverName);
			} catch (ClassNotFoundException e1) {
				e1.printStackTrace();
				return null;
			}

			List<String> columnNames = new ArrayList<>();
			List<String> columnTypes = new ArrayList<>();
			List<Integer> columnSizes = new ArrayList<>();
			Map<String, String> commentMap = new HashMap<>();

			con = DriverManager.getConnection(dsUrl, dsUserName, dsPassword);
			preparedStatement = con.prepareStatement(sql);
			ResultSetMetaData rsmd = preparedStatement.getMetaData();
			int size = rsmd.getColumnCount(); // 统计列

			// 读取comment
			ResultSet resultSet = null;
			{
				// 参考自:http://my.oschina.net/Thinkeryjgfn/blog/169384
				DatabaseMetaData metaData = con.getMetaData();
				String schema = dsUrl;
				if (schema.contains("?")) {
					schema = schema.substring(0, dsUrl.indexOf("?"));
				}
				schema = schema.substring(schema.lastIndexOf("/") + 1);
				resultSet = metaData.getColumns(con.getCatalog(), schema, tableName, null);
				if (StringUtils.contains(driverName, "mysql")) {// com.mysql.jdbc.Driver
					String commentSql = "select * from information_schema.tables where table_name='" + tableName + "' and table_schema='" + schema + "'";
					Statement stmt = con.createStatement();
					ResultSet executeQuery = stmt.executeQuery(commentSql);

					while (executeQuery.next()) {
						final String tableComment = executeQuery.getString("TABLE_COMMENT");
						tableBean.setTableComment(tableComment);
						break;
					}
				}
			}

			for (int i = 0; i < size; i++) {
				int next = i + 1;

				String columnName = rsmd.getColumnName(next);
				columnNames.add(columnName);
				boolean autoIncrement = rsmd.isAutoIncrement(next);
				if (autoIncrement) {
					tableBean.setAutoIncrementColumn(columnName);
				}

				String columnType = rsmd.getColumnTypeName(next).toLowerCase();
				columnTypes.add(columnType);

				int datasize = rsmd.getColumnDisplaySize(next);
				columnSizes.add(datasize);

				if (columnType.startsWith("datetime") || columnType.startsWith("date")) {
					tableBean.setFlagUtil(true);
				}
				if (columnType.startsWith("image") || columnType.startsWith("text")) {
					tableBean.setFlagSql(true);
				}
				if (columnType.startsWith("timestamp")) {
					tableBean.setFlagTimestamp(true);
				}
				if (resultSet != null) {
					resultSet.next();
					String comment = resultSet.getString("REMARKS");
					if (StringUtils.isNotBlank(comment)) {
						commentMap.put(columnName, comment);
					}
				}
			}
			tableBean.setColumnNames(columnNames.toArray(new String[columnNames.size()]));
			tableBean.setColumnTypes(columnTypes.toArray(new String[columnTypes.size()]));
			tableBean.setTableName(tableName);
			tableBean.setEntityName(transClassName(tableName));
			tableBean.setCommentMap(commentMap);
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (con != null) {
					con.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return tableBean;
	}

	/**
	 * transClassName
	 * @param tableName
	 * @return className
	 */
	private String transClassName(String tableName) {
		String tempTableName = tableName;
		if (!classNamePrefix.contains(Constants.VALUE_SIMPLE_SPLIT_CHAR)) {
			tempTableName = tableName.replace(classNamePrefix, "");
			return StringUtils.capitalize(StringUtils.camelName(tempTableName));
		} else {
			String[] split = classNamePrefix.split(",");
			for (String prefix : split) {
				if (tableName.toLowerCase().startsWith(prefix)) {
					tempTableName = tableName.replace(prefix, "");
					return StringUtils.capitalize(StringUtils.camelName(tempTableName));
				}
			}
		}
		return StringUtils.capitalize(StringUtils.camelName(tempTableName));
	}

	public void setClassNamePrefix(String classNamePrefix) {
		this.classNamePrefix = classNamePrefix;
	}
}
