package org.onetwo.common.spring.ftl;

import java.io.IOException;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;

/*****
 * 
 * [@str insertPrefix='where' trimPrefixs='and | or' trimSuffixs='and | or']
        [#if query.userName?has_content]
            u.user_name = :query.userName
        [/#if]
        [#if query.age??]
            and u.age = :query.age
        [/#if]
        [#if query.status??]
            and u.status = :query.status
        [/#if]
    [/@str]
    	
 * @author way
 *
 */
@SuppressWarnings("rawtypes")
public class StrDirective implements NamedDirective {
	
	public static final String DIRECTIVE_NAME = "str";

	public static final String SPLIT_CHAR = "|";
	public static final String PARAMS_INSERT_PREFIX = "insertPrefix";
	public static final String PARAMS_TRIM_PREFIXS = "trimPrefixs";
	public static final String PARAMS_TRIM_SUFFIXS = "trimSuffixs";

	@Override
	public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException {
		String insertPrefix = FtlUtils.getRequiredParameterByString(params, PARAMS_INSERT_PREFIX);
		String trimPrefixs = FtlUtils.getParameterByString(params, PARAMS_TRIM_PREFIXS, "");
		String trimSuffixs = FtlUtils.getParameterByString(params, PARAMS_TRIM_SUFFIXS, "");
		
		StringWriter writer = new StringWriter();
		body.render(writer);
		
		StringBuilder buffer = new StringBuilder(writer.toString().trim());
		if (StringUtils.isBlank(buffer)) {
			return ;
		}

		final String sql = buffer.toString().toLowerCase();
		
		trimPrefixs(buffer, sql, trimPrefixs);
		trimSuffixs(buffer, sql, trimSuffixs);
		
		buffer.insert(0, " ");
		buffer.insert(0, insertPrefix);
		env.getOut().append(buffer);
	}
	
	private void trimPrefixs(StringBuilder buffer, String sql, String trimPrefixs) {
		List<String> trimPrefixList = Arrays.asList(StringUtils.split(trimPrefixs.toLowerCase(), SPLIT_CHAR));
		for(String prefix : trimPrefixList) {
			if (sql.startsWith(prefix)) {
				buffer.delete(0, prefix.length());
				break;
			}
		}
	}
	
	private void trimSuffixs(StringBuilder buffer, String sql, String trimSuffixs) {
		List<String> trimSuffixList = Arrays.asList(StringUtils.split(trimSuffixs.toLowerCase(), SPLIT_CHAR));
		for(String suffix : trimSuffixList) {
			if (sql.endsWith(suffix)) {
				int start = buffer.length()-suffix.length();
				buffer.delete(start, buffer.length());
				break;
			}
		}
	}

	@Override
	public String getName() {
		return DIRECTIVE_NAME;
	}

}

@@ -1334,85 +1334,47 @@
 x = 
-FtlUtils.getRequiredParameterByString(params, PARAMS_INSERT_PREFIX);%0A%09%09
+getInsertPrefix(params);%0A%09%09List%3C
 String
+%3E
  tri
@@ -1388,80 +1388,46 @@
 s = 
-FtlUtils.getParameterByString(params, PARAMS_TRIM_PREFIXS, %22%22);%0A%09%09
+getTrimPrefixs(params);%0A%09%09List%3C
 String
+%3E
  tri
@@ -1441,69 +1441,29 @@
 s = 
-FtlUtils.getParameterByString(params, PARAMS_TRIM_SUFFIXS, %22%22
+getTrimSuffixs(params
 );%0A%09
@@ -1891,24 +1891,705 @@
 ffer);%0A%09%7D%0A%09%0A
+%09protected String getInsertPrefix(Map params) %7B%0A%09%09return FtlUtils.getRequiredParameterByString(params, PARAMS_INSERT_PREFIX);%0A%09%7D%0A%09%0A%09protected List%3CString%3E getTrimPrefixs(Map params) %7B%0A%09%09String trimPrefixs = FtlUtils.getParameterByString(params, PARAMS_TRIM_PREFIXS, %22%22);%0A%09%09List%3CString%3E trimPrefixList = Arrays.asList(StringUtils.split(trimPrefixs.toLowerCase(), SPLIT_CHAR));%0A%09%09return trimPrefixList;%0A%09%7D%0A%09%0A%09protected List%3CString%3E getTrimSuffixs(Map params) %7B%0A%09%09String trimSuffixs = FtlUtils.getParameterByString(params, PARAMS_TRIM_SUFFIXS, %22%22);%0A%09%09List%3CString%3E trimSuffixList = Arrays.asList(StringUtils.split(trimSuffixs.toLowerCase(), SPLIT_CHAR));%0A%09%09return trimSuffixList;%0A%09%7D%0A%09%0A
 %09private voi
@@ -2632,30 +2632,36 @@
 String sql, 
+List%3C
 String
+%3E
  trimPrefixs
@@ -2659,21 +2659,26 @@
 imPrefix
-s
+List
 ) %7B%0A
+//
 %09%09List%3CS
@@ -2971,22 +2971,28 @@
 ng sql, 
+List%3C
 String
+%3E
  trimSuf
@@ -2994,21 +2994,26 @@
 imSuffix
-s
+List
 ) %7B%0A
+//
 %09%09List%3CS

fix str directive