package com.iamberry.app.sqlprovider;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import org.apache.ibatis.jdbc.SQL;
import org.springframework.beans.factory.annotation.Qualifier;

/**
 * 
 * @author Sikandar
 * @date 2016年1月18日 下午9:34:48
 */
public class DMLProvider {

	/**
	 * update
	 * 
	 * @param map
	 * @return String
	 * @throws Exception
	 */
	public String update(Map<String, Object> map) {
		try {
			final String entityName = getEntityName(map);
			final Object object_ = map.get(entityName);
			final Class<?> cls = Class.forName(object_.getClass().getName());
			SQL sql = new SQL() {
				{
					Object id = null;
					UPDATE(entityName);
					for (Method method : cls.getDeclaredMethods()) {
						String mName = method.getName();
						if (mName.startsWith("get")) {
							Object rValue = method.invoke(object_);
							if (mName.equalsIgnoreCase("getId")) {
								id = rValue;
							} else {
								if (method.getReturnType() == String.class) {
									if (rValue != null)
										SET(mName.substring(mName.indexOf("get") + 3).toLowerCase() + " = '" + rValue + "'");
								} else if (method.getReturnType() == Date.class) {

									SimpleDateFormat format = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
									if (rValue != null)
										SET(mName.substring(mName.indexOf("get") + 3).toLowerCase() + " = '" + format.format(rValue) + "'");
								} else {
									if (rValue != null)
										SET(mName.substring(mName.indexOf("get") + 3).toLowerCase() + "=" + rValue.toString());
								}
							}
						}
					}

					WHERE("id = " + id);
				}
			};

			return sql.toString();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * insert
	 * 
	 * @param map
	 * @return String
	 */
	public String insert(Map<String, Object> map) {
		try {

			final String entityName = getEntityName(map);
			final Object object_ = map.get(entityName);
			final Class<?> cls = Class.forName(object_.getClass().getName());
			SQL sql = new SQL() {
				{
					INSERT_INTO(entityName);
					for (Method method : cls.getDeclaredMethods()) {
						String mName = method.getName();
						if (mName.startsWith("get")) {
							Object rValue = method.invoke(object_);
							if (method.getReturnType() == String.class) {
								if (rValue == null)
									VALUES(mName.substring(mName.indexOf("get") + 3).toLowerCase(), "" + rValue + "");
								else
									VALUES(mName.substring(mName.indexOf("get") + 3).toLowerCase(), "'" + rValue + "'");
							} else if (method.getReturnType() == Date.class) {

								SimpleDateFormat format = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
								if (rValue != null)
									VALUES(mName.substring(mName.indexOf("get") + 3).toLowerCase(), "'" + format.format(rValue) + "'");
								else
									VALUES(mName.substring(mName.indexOf("get") + 3).toLowerCase(), "" + null + "");
							} else
								VALUES(mName.substring(mName.indexOf("get") + 3).toLowerCase(), rValue == null ? "0" : rValue.toString());
						}
					}
				}
			};

			return sql.toString();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}

	}

	private String getEntityName(Map<String, Object> map) throws Exception {
		String entityName = null;
		for (Object object_ : map.values()) {
			Class<?> cls = Class.forName(object_.getClass().getName());
			for (Annotation annotation : cls.getAnnotations()) {
				if (annotation instanceof Qualifier) {
					Qualifier myAnnotation = (Qualifier) annotation;
					entityName = myAnnotation.value();
				}
			}
		}

		if (entityName == null)
			throw new Exception(
					"@Qualifier not found, Entity should be defined with @Qualifier name, @Qualifier name must match DataBase table name");
		return entityName;

	}

}
