package com.ylcm.sys.common;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.sf.json.JSONObject;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;

/**
 * @author Administrator
 * 
 * js、sql等是否存在注入检查
 */
public class InjectCheckUtil {
	
	private static final Pattern sql_keyword = Pattern.compile(
			"(/\\*(?:.|[\\n\\r])*?\\*/)|"  
            + "(\\b(select|update|delete|insert|trancate|into|substr|ascii|declare|exec|count|into|drop|execute)\\b)",
			Pattern.CASE_INSENSITIVE);
	private static final Pattern script_keyword = Pattern.compile("<[\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>", Pattern.CASE_INSENSITIVE);
	private static final Pattern href_keyword = Pattern.compile("(href *= *[\\s\\S]*script*:)", Pattern.CASE_INSENSITIVE);
	private static final Pattern iframe_keyword = Pattern.compile("<[\\s]*?iframe[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?iframe[\\s]*?>", Pattern.CASE_INSENSITIVE);
	private static final Pattern style_keyword = Pattern.compile("<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>", Pattern.CASE_INSENSITIVE);


	private static final Pattern number = Pattern.compile("[0-9]+");
	private static final Pattern letter = Pattern.compile("[a-z]+", Pattern.CASE_INSENSITIVE);

	public static boolean include(byte[] barr, byte b0) {
		boolean result = false;
		for (byte b : barr)
			result |= (b == b0);
		return result;
	}
	
	/**
	 * 验证长度 验证注入（sql、javascript）
	 * 
	 * @param input
	 * @return true 非法 ；false 合法
	 */
	public static boolean filterInject(String input) {
		if (null == input) {
			return true;
		}
		Matcher m_sql = sql_keyword.matcher(input);
		Matcher m_js = script_keyword.matcher(input);
		return m_sql.find() || m_js.find() || href_keyword.matcher(input).find() || iframe_keyword.matcher(input).find() || style_keyword.matcher(input).find();
	}

	/**
	 * 
	 * 验证长度 验证注入（sql、javascript）
	 * 
	 * @param input
	 * @param length
	 *            content最大长度
	 * @return true 非法 ；false 合法
	 */
	public static boolean inputMatch(String input, int length) {
		if (StringUtils.isBlank(input)) {
			return true;
		}
		if (Util.countWords(input) > length) {
			return true;
		}
		return false;
	}

	public static String object2string(Object input) {
		return null == input ? "" : input.toString();
	}

	public static Long object2long(Object input) {
		return (null == input || !(input instanceof Long)) ? 0 : (Long) input;
	}

	public static Integer object2int(Object input) {
		return (null == input || !(input instanceof Integer)) ? 0
				: (Integer) input;
	}

	public static Byte object2byte(Object input) {
		return (null == input || !(input instanceof Byte)) ? 0 : (Byte) input;
	}

	public static java.sql.Date object2date(Object input) {
		return (null == input || !(input instanceof java.sql.Date)) ? null
				: (java.sql.Date) input;
	}

	public static Timestamp object2timestamp(Object input) {
		return (null == input || !(input instanceof Timestamp)) ? null
				: (Timestamp) input;
	}

	public static Long string2long(String input) {
		long result = 0;

		if (!StringUtils.isBlank(input)) {
			result = isNumeric(input) ? Long.parseLong(input) : 0;
		}

		return result;
	}

	public static int string2int(String input) {
		int result = 0;

		if (!StringUtils.isBlank(input)) {
			result = isNumeric(input) ? Integer.parseInt(input) : 0;
		}

		return result;
	}

	public static Boolean string2boolean(String input) {
		return Boolean.valueOf(input);
	}

	public static Byte string2byte(String input) {
		byte result = 0;

		if (!StringUtils.isBlank(input)) {
			result = isNumeric(input) ? Byte.parseByte(input) : 0;
		}

		return result;
	}

	public static List<List<String>> paramSplit(Object input) {
		List<List<String>> result = new ArrayList<List<String>>();
		String param = object2string(input);
		if (StringUtils.isNotBlank(param)) {
			String[] lines = param.split("[;]");
			for (String line : lines) {
				String[] rows = line.split("[,]");
				result.add(Arrays.asList(rows));
			}
		}
		return result;
	}

	public static boolean isNumeric(String input) {
		Matcher m = number.matcher(input);
		return m.matches();
	}

	public static boolean isEnLetters(String input) {
		Matcher m = letter.matcher(input);
		return m.matches();
	}

	public static int getym(Date date) {
		Calendar c = Calendar.getInstance();

		c.setTime(date);

		int y = c.get(Calendar.YEAR);
		int m = c.get(Calendar.MONTH) + 1;

		return y * 100 + m;
	}

	public static void main(String[] args) throws Exception {
		System.out.println(StringEscapeUtils.escapeJavaScript("http://localhost:8080/ssesns/user/index.do"));
		
		System.out.println(script_keyword.matcher("<script>alert(document.cookie)</script>").find());
		System.out.println(iframe_keyword.matcher("<iframe>x</iframe>").find());
		
		System.out.println(StringEscapeUtils.escapeHtml("{ \"firstName\": \"Brett\", \"lastName\":\"McLaughlin\", \"email\": \"aaaa\" }"));
	
		System.out.println("<a href='user.do?uid=9' >@遥指科技(888888)</a>手机测试".replaceAll("(<a href='user\\.do\\?uid=\\d+' >@.*\\(\\d{6}\\)</a>)",
				""));
		
		System.out.println(filterInject("insert"));
	}

	/**
	 * sse请求
	 * 
	 * @param url
	 *            请求URL
	 * @param input
	 *            请求参数
	 * @param timeout
	 *            超时时间(毫秒)
	 * @return Json字符串
	 * @throws Exception
	 */
	public static JSONObject requestUrl_2(URL url, String input, String timeout)
			throws Exception {
		/**
		 * 1，指定url错误，则返回电信错误页面，返回的将不是json字符串 2，如果访问压力大，返回500错误
		 */
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setDoOutput(true);
		conn.setDoInput(true);
		conn.setRequestMethod("POST");
		conn.setUseCaches(false);
		conn.setInstanceFollowRedirects(true);
		conn.setRequestProperty("Content-Type",
				"application/x-www-form-urlencoded;charset=gbk");

		// 设定连接超时（毫秒级）
		conn.setConnectTimeout(getConnTimeout(timeout));
		conn.getOutputStream().write(input.getBytes());
		conn.connect();

		// 接收返回值
		String s = null;
		InputStream is = null;
		BufferedReader br = null;

		StringBuffer buf = new StringBuffer();

		try {
			is = conn.getInputStream();
			br = new BufferedReader(new InputStreamReader(is, "gbk"));
			while ((s = br.readLine()) != null) {
				buf.append(s);
			}
		} finally {
			if (null != br)
				br.close();

			if (null != is)
				is.close();
		}

		return JSONObject.fromObject(buf.toString());
	}

	@Deprecated
	public static JSONObject requestUrl(URL url, String timeout)
			throws Exception {
		/**
		 * 1，指定url错误，则返回电信错误页面，返回的将不是json字符串 2，如果访问压力大，返回500错误
		 */
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setDoOutput(true);
		conn.setDoInput(true);
		conn.setRequestMethod("POST");
		conn.setUseCaches(false);
		conn.setInstanceFollowRedirects(true);
		conn.setRequestProperty("Content-Type",
				"application/x-www-form-urlencoded;charset=gbk");
		// 设定连接超时（毫秒级）
		conn.setConnectTimeout(getConnTimeout(timeout));
		conn.connect();

		// 接收返回值
		String s = null;
		InputStream is = null;
		BufferedReader br = null;

		StringBuffer buf = new StringBuffer();

		try {
			is = conn.getInputStream();
			br = new BufferedReader(new InputStreamReader(is));
			while ((s = br.readLine()) != null) {
				buf.append(s);
			}
		} finally {
			if (null != br)
				br.close();

			if (null != is)
				is.close();
		}

		return JSONObject.fromObject(buf.toString());
	}

	/**
	 * 
	 * 连接超时设定，大小控制在5000~30000豪秒
	 * 
	 * @param input
	 * @return
	 */
	private static int getConnTimeout(String input) {
		// 如果是非数字型，则返回0
		int result = InjectCheckUtil.string2int(input);

		// 设定下限为5秒
		if (5 > result) {
			result = 5;
		}

		// 设定上限为30秒
		if (30 < result) {
			result = 30;
		}

		return result * 1000;
	}

	public static String utf2gbk(String input)
			throws UnsupportedEncodingException {
		return URLEncoder.encode(input, "gbk");
	}

	public static String gbk2utf8(String input)
			throws UnsupportedEncodingException {
		return new String(input.getBytes("GBK"), "UTF-8");
	}

}
