package com.njcn.utils;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
 * @author hongawen //denghuajun
 * @version 1.0
 * @Date 2018/4/20 9:00
 */
public class XssFilterUtil {

	/**
	 * 处理参数值
	 * @param parameters 字符数组
	 */
	public static String[] dealStringArray(String[] parameters) {
		if (ArrayUtils.isEmpty(parameters)) {
			return null;
		}
		int count = parameters.length;
		String[] encodedValues = new String[count];
		for (int i = 0; i < count; i++) {
			encodedValues[i] = dealString(parameters[i]);
		}
		return encodedValues;
	}

	/**
	 * 处理参数值
	 * @param parameters 字符集合
	 */
	public static  String[] dealStringList(List<String> parameters) {
		if (CollectionUtils.isEmpty(parameters)) {
			return null;
		}
		int count = parameters.size();
		String[] encodedValues = new String[count];
		for (int i = 0; i < count; i++) {
			encodedValues[i] = dealString(parameters.get(i));
		}
		return encodedValues;
	}

	/**
	 * 滤除content中的危险 HTML 代码, 主要是脚本代码, 滚动字幕代码以及脚本事件处理代码
	 *
	 * @param content
	 *            需要滤除的字符串
	 * @return 过滤的结果
	 */
	public static String replaceHtmlCode(String content) {
		if (null == content) {
			return null;
		}
		if (0 == content.length()) {
			return "";
		}
		// 需要滤除的脚本事件关键字
		String[] eventKeywords = { "onmouseover", "onmouseout", "onmousedown",
				"onmouseup", "onmousemove", "onclick", "ondblclick",
				"onkeypress", "onkeydown", "onkeyup", "ondragstart",
				"onerrorupdate", "onhelp", "onreadystatechange", "onrowenter",
				"onrowexit", "onselectstart", "onload", "onunload",
				"onbeforeunload", "onblur", "onerror", "onfocus", "onresize",
				"onscroll", "oncontextmenu", "alert" };
		content = replace(content, "<script", "<script", false);
		content = replace(content, "</script", "</script", false);
		content = replace(content, "<marquee", "<marquee", false);
		content = replace(content, "</marquee", "</marquee", false);
//		content = replace(content, "'", "_", false);// 将单引号替换成下划线
//		content = replace(content, "\"", "_", false);// 将双引号替换成下划线
		// 滤除脚本事件代码
		for (int i = 0; i < eventKeywords.length; i++) {
			content = replace(content, eventKeywords[i],
					"_" + eventKeywords[i], false); // 添加一个"_", 使事件代码无效
		}
		return content;
	}

	/**
	 * 将字符串 source 中的 oldStr 替换为 newStr, 并以大小写敏感方式进行查找
	 *
	 * @param source
	 *            需要替换的源字符串
	 * @param oldStr
	 *            需要被替换的老字符串
	 * @param newStr
	 *            替换为的新字符串
	 */
	private static String replace(String source, String oldStr, String newStr) {
		return replace(source, oldStr, newStr, true);
	}

	/**
	 * 将字符串 source 中的 oldStr 替换为 newStr, matchCase 为是否设置大小写敏感查找
	 *
	 * @param source
	 *            需要替换的源字符串
	 * @param oldStr
	 *            需要被替换的老字符串
	 * @param newStr
	 *            替换为的新字符串
	 * @param matchCase
	 *            是否需要按照大小写敏感方式查找
	 */
	private static String replace(String source, String oldStr, String newStr,
	                              boolean matchCase) {
		if (source == null) {
			return null;
		}
		// 首先检查旧字符串是否存在, 不存在就不进行替换
		if (source.toLowerCase().indexOf(oldStr.toLowerCase()) == -1) {
			return source;
		}
		int findStartPos = 0;
		int a = 0;
		while (a > -1) {
			int b = 0;
			String str1, str2, str3, str4, strA, strB;
			str1 = source;
			str2 = str1.toLowerCase();
			str3 = oldStr;
			str4 = str3.toLowerCase();
			if (matchCase) {
				strA = str1;
				strB = str3;
			} else {
				strA = str2;
				strB = str4;
			}
			a = strA.indexOf(strB, findStartPos);
			if (a > -1) {
				b = oldStr.length();
				findStartPos = a + b;
				StringBuffer bbuf = new StringBuffer(source);
				source = bbuf.replace(a, a + b, newStr) + "";
				// 新的查找开始点位于替换后的字符串的结尾
				findStartPos = findStartPos + newStr.length() - b;
			}
		}
		return source;
	}

	public static String xssEncode(String s) {
		if (s == null || s.isEmpty()) {
			return s;
		}
		StringBuilder sb = new StringBuilder(s.length() + 16);
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			switch (c) {
				case '>':
					sb.append('＞');// 全角大于号
					break;
				case '<':
					sb.append('＜');// 全角小于号
					break;
//				case '\'':
//					sb.append('‘');// 全角单引号
//					break;
//				case '\"':
//					sb.append('“');// 全角双引号
//					break;
//				case '&':
//					sb.append('＆');// 全角
//					break;
				case '\\':
					sb.append('＼');// 全角斜线
					break;
				/*case '#':
					sb.append('＃');// 全角井号
					break;*/
//				case '(':
//					sb.append('（');//
//					break;
//				case ')':
//					sb.append('）');//
//					break;
				default:
					sb.append(c);
					break;
			}
		}
		String resultStr = sb.toString();
//		resultStr=StringEscapeUtils.escapeSql(resultStr);
//		resultStr=StringEscapeUtils.escapeHtml(resultStr);
//		resultStr=StringEscapeUtils.escapeJavaScript(resultStr);
		return resultStr;
	}

	/**
	 * 字符串处理包括SQL的注入处理
	 * @author hongawen
	 * @param value 字符串
	 */
	public static String dealString(String value) {
		if (!StringUtils.isBlank(value)) {
			value = xssEncode(value);
			value=replaceHtmlCode(value);
			value=StringEscapeUtils.escapeSql(value);
			return value;
		}else{
			return "";
		}
	}
}
