package cn.hmsoft.frame.control;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import cn.hmsoft.application.AppHelper;
import cn.hmsoft.application.SpringHelper;
import cn.hmsoft.application.web.Ajax;
import cn.hmsoft.application.web.AjaxControl;
import cn.hmsoft.helper.LocalDateHelper;
import cn.hmsoft.helper.SecureHelper;
import cn.hmsoft.helper.StringHelper;
import cn.hmsoft.jdbc.entity.ColumnEntity;
import cn.hmsoft.jdbc.entity.TableEntity;

@RestController
public class FrameDebugControl extends AjaxControl {
	@RequestMapping("debug/index")
	public void index(HttpServletRequest request, HttpServletResponse response) {
		// 如果不是调试模式,不允许返回任何信息
		if (!AppHelper.AppDebug)
			return;
		List<TableEntity> tables = SpringHelper.AppGobalDao.getTables();
		StringBuilder sb = new StringBuilder();
		sb.append(" \n");
		sb.append(
				"<!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'> \n");
		sb.append("<html> \n");
		sb.append("<head> \n");
		sb.append("<title>启航java平台开发工具-类生成器</title> \n");
		sb.append("<meta http-equiv='content-type' content='text/html; charset=utf8' /> \n");
		sb.append("<style type='text/css'> \n");
		sb.append("body{  \n");
		sb.append("background: #f5faff; \n");
		sb.append("} \n");
		sb.append(".demo_con{ \n");
		sb.append("width: 960px; \n");
		sb.append("margin:40px auto 0; \n");
		sb.append("} \n");
		sb.append(".button{ \n");
		sb.append("width: 80px; \n");
		sb.append("line-height: 28px; \n");
		sb.append("text-align: center; \n");
		sb.append("font-weight: bold; \n");
		sb.append("color: #fff; \n");
		sb.append("text-shadow:1px 1px 1px #333; \n");
		sb.append("border-radius: 5px; \n");
		sb.append("margin:0 0 0 0; \n");
		sb.append("position: relative; \n");
		sb.append("overflow: hidden; \n");
		sb.append("cursor:pointer; \n");
		sb.append("} \n");
		sb.append(".button.blue{ \n");
		sb.append("border:1px solid #1e7db9; \n");
		sb.append("box-shadow: 0 1px 2px #8fcaee inset,0 -1px 0 #497897 inset,0 -2px 3px #8fcaee inset; \n");
		sb.append("background: -webkit-linear-gradient(top,#42a4e0,#2e88c0); \n");
		sb.append("background: -moz-linear-gradient(top,#42a4e0,#2e88c0); \n");
		sb.append("background: linear-gradient(top,#42a4e0,#2e88c0); \n");
		sb.append("} \n");
		sb.append(".select_style {width:320px; height:30px; overflow:hidden;  \n");
		sb.append("border:1px solid #ccc;  \n");
		sb.append("-moz-border-radius: 5px; /* Gecko browsers */  \n");
		sb.append("-webkit-border-radius: 5px; /* Webkit browsers */  \n");
		sb.append("border-radius:5px;  \n");
		sb.append("}  \n");
		sb.append(
				".select_style select { padding:5px; background:transparent; width:320px; font-size: 16px; border:none; height:30px;  \n");
		sb.append("-webkit-appearance: none; /*for Webkit browsers*/  \n");
		sb.append("}  \n");
		sb.append(".editTextarea{ \n");
		sb.append("border-radius: 5px; \n");
		sb.append("margin:0 0 0 0; \n");
		sb.append("position: relative; \n");
		sb.append("} \n");
		sb.append("</style> \n");
		sb.append("<script> \n");
		sb.append("	var request = false; \n");
		sb.append("	try { \n");
		sb.append("		request = new XMLHttpRequest(); \n");
		sb.append("	} catch (trymicrosoft) { \n");
		sb.append("		try { \n");
		sb.append("			request = new ActiveXObject('Msxml2.XMLHTTP'); \n");
		sb.append("		} catch (othermicrosoft) { \n");
		sb.append("			try { \n");
		sb.append("				request = new ActiveXObject('Microsoft.XMLHTTP'); \n");
		sb.append("			} catch (failed) { \n");
		sb.append("				request = false; \n");
		sb.append("			} \n");
		sb.append("		} \n");
		sb.append("	} \n");
		sb.append("	if (!request) \n");
		sb.append("		alert('Error initializing XMLHttpRequest!'); \n");
		sb.append(" \n");
		sb.append("	function showClass() { \n");
		sb.append("		if (request.readyState == 4) \n");
		sb.append("			if (request.status == 200) { \n");
		sb.append("				document.getElementById('className').value = request.responseText; \n");
		sb.append("			} else if (request.status == 404) \n");
		sb.append("				alert('Request URL does not exist'); \n");
		sb.append("			else \n");
		sb.append("				alert('Error: status code is ' + request.status); \n");
		sb.append("	} \n");
		sb.append("	function goGenerate(type) { \n");
		sb.append("		var tableName = document.all('tableName').value; \n");
		sb.append("		//alert(tableName.length); \n");
		sb.append("		if (tableName.length == 0) \n");
		sb.append("			return; \n");
		sb.append("		var url = '" + SpringHelper.WebServletContext.getContextPath()
				+ "/debug/code/generate.htm?tableName='+ tableName+'&type=' + type; \n");
		sb.append("		request.open('POST', url, true); \n");
		sb.append("		request.onreadystatechange = showClass; \n");
		sb.append("		request.send(null); \n");
		sb.append("	} \n");
		sb.append("</script> \n");
		sb.append("</head> \n");
		sb.append("<body> \n");
		sb.append("		<table align='center' valign='center'> \n");
		sb.append("			<tr> \n");
		sb.append("				<td><div class='select_style'>  \n");
		sb.append("<select name='tableName'>  \n");
		for (TableEntity dr : tables) {
			String v = "";
			try {
				if (StringHelper.isNotEmpty(dr.getTable_comment()))
					v = dr.getTable_comment().split(";")[0];
			} catch (Exception e) {

			}
			sb.append("<option value='" + dr.getTable_name().toUpperCase() + "'>" + dr.getTable_name().toUpperCase()
					+ (StringHelper.isEmpty(v) ? "" : ("(" + v + ")")) + "</option> ");
		}

		sb.append("</select>  \n");
		sb.append("</div></td> \n");
		sb.append(
				"				<td align='right'><input type='button' value='Class' class='button blue' onclick=\"goGenerate('class')\" /></td> \n");
		sb.append(
				"				<td align='right'><input type='button' value='Field' class='button blue' onclick=\"goGenerate('field')\" /></td> \n");
		sb.append(
				"				<td align='right'><input type='button' value='Column' class='button blue' onclick=\"goGenerate('column')\" /></td> \n");
		sb.append(
				"				<td align='right'><input type='button' value='Json' class='button blue' onclick=\"goGenerate('json')\" /></td> \n");
		sb.append("			</tr> \n");
		sb.append("			<tr> \n");
		sb.append(
				"				<td colspan='5'><textarea  class='editTextarea' rows='35' id='className' cols='80' readonly='readonly'></textarea></td> \n");
		sb.append("			</tr> \n");
		sb.append(" \n");
		sb.append("		</table> \n");
		sb.append("</body> \n");
		sb.append("</html> \n");

		response.setCharacterEncoding("UTF-8");
		response.setHeader("Content-type", "text/html;charset=UTF-8");
		try {
			response.getWriter().write(sb.toString());
			response.getWriter().flush();
			response.getWriter().close();
		} catch (Exception e) {

		}
	}

	@RequestMapping("/debug/code/generate")
	public void generate(HttpServletRequest request, HttpServletResponse response, String tableName, String type)
			throws Exception {

		if (!AppHelper.AppDebug)
			return;
		response.setCharacterEncoding("UTF-8");
		response.setHeader("Content-type", "text/html;charset=UTF-8");

		String value = "";
		if (type.equals("class"))
			value = this.generateEntityClass(tableName);
		else if (type.equalsIgnoreCase("field"))
			value = this.generateStoreField(tableName);
		else if (type.equalsIgnoreCase("json")) {
			value = this.generateEntityJson(tableName);
		}
		try {
			response.getWriter().write(value);
			response.getWriter().flush();
			response.getWriter().close();
		} catch (Exception e) {

		}
		return;
	}

	private String generateStoreField(String tableName) throws Exception {
		List<ColumnEntity> list = SpringHelper.AppGobalDao.getColumns(tableName);
		StringBuilder sb = new StringBuilder("");
		for (ColumnEntity dr : list) {
			String fieldName = dr.getColumn_name().toLowerCase();
			sb.append("'" + fieldName + "',");
		}
		sb.deleteCharAt(sb.length() - 1);
		return sb.toString();

	}

	private String generateEntityJson(String tableName) {
		List<ColumnEntity> list = SpringHelper.AppGobalDao.getColumns(tableName);
		StringBuilder sb = new StringBuilder("{");
		sb.append("\n");
		for (ColumnEntity dr : list) {
			String fieldName = dr.getColumn_name().toLowerCase();
			String columnDes = dr.isNullable() ? "非空" : "可空";
			sb.append("\"" + fieldName + "\":\"" + dr.getColumn_type() + "," + columnDes + "\",").append("\n");
		}
		sb.deleteCharAt(sb.length() - 2);
		sb.append("}");
		return sb.toString();
	}

	/*****
	 * 根据表名生成实体类
	 */
	private String generateEntityClass(String tableName) throws Exception {
		List<ColumnEntity> list = SpringHelper.AppGobalDao.getColumns(tableName);

		List<TableEntity> tables = SpringHelper.AppGobalDao.getTables();

		String tableDesc = "";
		for (TableEntity dr : tables) {
			if (dr.getTable_name().toUpperCase().equals(tableName)) {
				String v = "";
				try {
					if (StringHelper.isNotEmpty(dr.getTable_comment()))
						v = dr.getTable_comment().split(";")[0];
				} catch (Exception e) {

				}
				tableDesc = v;
				break;
			}
		}
		StringBuilder sb = new StringBuilder();
		sb.append("import java.io.Serializable;\n");
		sb.append("import cn.hmsoft.jdbc.entity.Table;\n");
		sb.append("{import}\n");

		sb.append("/**********************************************\n");
		sb.append("* " + tableDesc + "\n");
		sb.append("* @author: zxq\n");
		sb.append("* @date: " + LocalDateHelper.format(LocalDateTime.now()) + "\n");
		sb.append("* @version: 2.0.0\n");
		sb.append("* @email: revisit@126.com\n");
		sb.append("* @Company: www.hmsoft.cn\n");
		sb.append("*/\n");
		sb.append("@Table(tableName = \"" + tableName.toUpperCase()
				+ "\", keyColumn =  {keyColumn} , sequenceName = \"\")\n");

		sb.append("public class " + StringHelper.toClassName(tableName) + " implements Serializable{\n");
		// private static final long serialVersionUID = -1085129669120254141L;
		sb.append("\tprivate static final long serialVersionUID = " + new Random().nextLong() + "L;\n");
		sb.append("{field}\n");
		sb.append("{method}\n");
		sb.append("}");
		StringBuilder sf = new StringBuilder();
		StringBuilder sm = new StringBuilder();
		StringBuilder sp = new StringBuilder();
		List<String> sk = new ArrayList<String>();
		for (ColumnEntity dr : list) {
			// DataType s10;
			String type = "";
			String data_type = dr.getColumn_type().toLowerCase();
			// System.out.println(data_type);
			if (data_type.equals("varchar") || data_type.equals("varchar2")) {
				type = "String";
			} else if (data_type.equals("int") || data_type.equals("number") || data_type.equals("integer")) {
				type = "Integer";
			} else if (data_type.equals("date") || data_type.equals("datetime")) {
				type = "LocalDateTime";
				if (sp.indexOf("java.time.LocalDateTime;") < 0)
					sp.append("import java.time.LocalDateTime;\n");
			} else if (data_type.equals("float") || data_type.equals("long")) {
				// 判断小数点 concat(NUMERIC_SCALE,'') as s09
				type = "Integer";
			} else if (data_type.equalsIgnoreCase("double")) {
				type = "Double";
			} else
				type = "String";
			String fieldName = dr.getColumn_name().toLowerCase();
			String fieldComment = dr.getColumn_comment();
			if (StringHelper.isNotEmpty(fieldComment)) {
				sf.append("\t//" + fieldComment + "\n");
			}
			sf.append("\tprivate " + type + " " + fieldName + ";\n");

			if (StringHelper.isNotEmpty(fieldComment)) {
				sm.append("\t/****\n");
				sm.append("\t * " + fieldComment + "\n");
				sm.append("\t */\n");
			}
			sm.append("\tpublic " + type + " get" + StringHelper.upperFirstChar(fieldName) + "() {\n");
			sm.append("\t\treturn this." + fieldName + ";\n");
			sm.append("\t}\n\n");

			// s06 comment
			if (StringHelper.isNotEmpty(fieldComment)) {
				sm.append("\t/****\n");
				sm.append("\t * " + fieldComment + "\n");
				sm.append("\t */\n");
			}
			sm.append("\tpublic void set" + StringHelper.upperFirstChar(fieldName) + "(" + type + " " + fieldName
					+ ") {\n");
			sm.append("\t\tthis." + fieldName + " = " + fieldName + ";\n");
			sm.append("\t}\n\n");

			// 判断主键 S05
			// if (StringHelper.isNotEmpty(dr.getS05()) &&
			// dr.getS05().toUpperCase().equals("PRI")) {
			// sk.add(dr.getS01().toUpperCase());
			// }
		}
		String keyValue = "";
		if (sk.size() == 1) {
			// for (int i = 0; i < sk.size() - 1; i++) {
			// keyValue = keyValue + "\"" + sk.get(i) + "\",";
			// }
			keyValue = keyValue + "\"" + sk.get(0) + "\"";
		} else
			keyValue = "\"\"";
		return sb.toString().replace("{import}", sp.toString()).replace("{keyColumn}", keyValue)
				.replace("{field}", sf.toString()).replace("{method}", sm.toString());

	}

	@RequestMapping("debug/secure/key")
	public Ajax key(String value) {
		// AssertUtil.isNotEmpty(value, "请提交需要加密的字符串");
		// 如果不是调试模式,不允许返回任何信息
		if (!AppHelper.AppDebug)
			return new Ajax();
		byte[] key = SecureHelper.getSecureKey(SpringHelper.WebServletContext.getContextPath().replace("/", ""));
		return new Ajax(SecureHelper.des3Encrypt(value, key));
	}
}
