package com.hotent.base.ognl;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.hotent.base.util.BeanUtils;
import com.hotent.base.util.MapUtil;
import com.hotent.base.util.StringUtil;
import com.hotent.base.util.ThreadMsgUtil;

/**
 * Ognl工具类
 * <p>
 * 主要是为了在ognl表达式访问静态方法时可以减少长长的类名称编写 Ognl访问静态方法的表达式
 * </p>
 * @class@method(args) 示例使用
 * <pre>
 * &lt;if test=&quot;@Ognl@isNotEmpty(userId)&quot;&gt;
 * 	and user_id = #{userId}
 * &lt;/if&gt;
 * </pre>
 *
 * @company 广州宏天软件股份有限公司
 * @author heyifan
 * @email heyf@jee-soft.cn
 * @date 2018年6月4日
 */
public class Ognl {
	/**
	 * 可以用于判断 Map,Collection,String,Array,Long是否为空
	 * 
	 * @param o
	 *            java.lang.Object.
	 * @return boolean.
	 */
	public static boolean isEmpty(Object o) throws IllegalArgumentException {
		return BeanUtils.isEmpty(o);
	}

	/**
	 * 可以用于判断 Map,Collection,String,Array是否不为空
	 * 
	 * @param c
	 * @return
	 */
	public static boolean isNotEmpty(Object o) {
		return !isEmpty(o);
	}

	/**
	 * 可以用于判断Long类型是否不为空
	 * 
	 * @param c
	 * @return
	 */
	public static boolean isNotEmpty(Long o) {
		return !isEmpty(o);
	}

	/**
	 * 判断是否为数字
	 * 
	 * @param o
	 * @return
	 */
	public static boolean isNumber(Object o) {
		return BeanUtils.isNumber(o);
	}

	/**
	 * 判断是否相等
	 * 
	 * @param o1
	 * @param o2
	 * @return
	 */
	public static boolean equals(Object o1, Object o2) {
		return o1.equals(o2);
	}
	/**
	 * 判断是否相等
	 * 
	 * @param o1
	 * @param o2
	 * @return
	 */
	public static boolean notEquals(Object o1, Object o2) {
		return !equals(o1, o2);
	}

	/**
	 * o1是否以o2开头（忽略空格和大小写）
	 * @param o1
	 * @param o2
	 * @return
	 */
	public static boolean startsWith(Object o1, Object o2) {
		if(o1==null || !(o1 instanceof String) || o2==null || !(o2 instanceof String)) {
			return false;
		}
		return o1.toString().trim().startsWith(o2.toString().trim()) 
			|| o1.toString().trim().startsWith(o2.toString().trim().toLowerCase())
			|| o1.toString().trim().startsWith(o2.toString().trim().toUpperCase());
	}

	/**
	 * 去掉mp构建的查询条件中默认追加的where
	 * @param o1
	 * @return
	 */
	public static Object withOutWhere(Object o1) {
		if(o1 != null && o1 instanceof String) {
			String str = o1.toString().trim();
			if(str.length() > 6 && (str.startsWith("where") || str.startsWith("WHERE"))) {
				return str.substring(6);
			}
		}
		return o1;
	}

	/**
	 * order by 前插入filterSql
	 * @param o1
	 * @param o2
	 * @return
	 */
	public static Object insertBeforeOrderBy(Object o1, Object o2){
		// 条件二为空则无需拼接
		if(isEmpty(o2)) {
			return !isEmpty(o1)?o1.toString():"";
		}
		
		StringBuilder sql1 = new StringBuilder(isNotEmpty(o1) ? o1.toString().trim().replaceAll("\r|\n", " ") : " WHERE ");
		String sql2 = o2.toString().trim().replaceAll("\r|\n", " ")+" ";
		int index = sql1.toString().toUpperCase().indexOf("ORDER BY");
		// sql1为空或者以ORDER BY开头，则sql2需要去掉开头的and、or
		if(isEmpty(o1) || index == 0) {
			if(sql2.toUpperCase().startsWith("AND ")) {
				sql2 = sql2.substring(3, sql2.length());
			}else if(sql2.toUpperCase().startsWith("OR ")) {
				sql2 = sql2.substring(2, sql2.length());
			}
		}else if (!sql2.toUpperCase().startsWith("AND ") && !sql2.toUpperCase().startsWith("OR ")) {
			sql2=" AND "+sql2;
		}
		
		if (index > -1){
			//如果sql2包含WHERE和ORDER BY，则将sql2插入sql1的ORDER BY之前
			if (sql1.toString().trim().toUpperCase().startsWith("WHERE")){
				sql1.insert(index, sql2);
				return sql1.toString();
			}else{//sql1不包含where,只有ORDER BY。则将sql2添加到sql1的前面，并且拼上where
				return String.format(" WHERE %s %s", sql2, sql1.toString());
			}
		}else{
			return String.format(" %s %s", sql1.toString(), sql2);
		}
	}
	
	/**
	 * 判断sql中是否包含where
	 * @param o
	 * @return
	 */
	public static boolean containsWhere(Object o){
		if (BeanUtils.isEmpty(o)) {
			return false;
		}
		
		Pattern pattern = Pattern.compile("\\b(where)\\b");
		Matcher matcher = pattern.matcher(o.toString().toLowerCase().replaceAll("\r|\n", " ").replaceAll("\\([\\s\\S]*\\)", ""));
		return matcher.find();
		
	}
	
	public static Object encodeValue(List<Map<String,Object>> valueList,int index,String key) {
		return String.format("#{valueList[%s].%s}",index,key);
	}
	
	public static boolean containsKey(List<Map<String,Object>> valueList,int index,String key) {
		if("true".equals(ThreadMsgUtil.getMapMsg(ThreadMsgUtil.IGNORE_FORM_DATA_REV))) {
			return false;
		}
		return MapUtil.containsIgnoreKey(valueList.get(index), key);
	}
	
	public static int getOldFormDataRev(List<Map<String,Object>> valueList,int index,String key) {
		Map<String, Object> map = valueList.get(index);
		Object valueOfObj = MapUtil.getIgnoreCase(map, key);
		if (valueOfObj == null) {
			return 0;
		}
		String valueOfStr = String.valueOf(valueOfObj);
		if (StringUtil.isEmpty(valueOfStr) || "null".equalsIgnoreCase(valueOfStr)) {
			return 0;
		}
		Integer value = Integer.parseInt(valueOfStr);
		return value > 0 ? value - 1 : value;
	}
	
	public static boolean isCollection(Object o){
		if (BeanUtils.isEmpty(o)) {
			return false;
		}
		if (o instanceof Collection) {
			return true;
		}
		return false;
	}
	
	
}
