package org.jim.common.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 本类部分代码参考了voovan项目，不过为了适应需要，作了部分改动，感谢作者的贡献
 * 项目地址： http://www.voovan.org/
 * @author wchao
 * 2017年7月27日 上午10:09:19
 */
public class HttpParseUtils {
	//	private static Logger log = LoggerFactory.getLogger(HttpParseUtils.class);

	/**
	 * 【------------------------------------------------------------------------------------
	 * 以下代码参考了voovan项目，不过为了适应需要，作了部分改动，感谢作者的贡献
	 * 项目地址： http://www.voovan.org/
	 * ------  start  ------
	 */
	private static ConcurrentHashMap<Integer, Pattern> regexPattern = new ConcurrentHashMap<>();

	private static Pattern getCachedPattern(String regex) {
		Pattern pattern = null;
		if (regexPattern.containsKey(regex.hashCode())) {
			pattern = regexPattern.get(regex.hashCode());
		} else {
			pattern = Pattern.compile(regex);
			regexPattern.put(regex.hashCode(), pattern);
		}
		return pattern;
	}

	/**
	 * 解析字符串中的所有等号表达式成 Map
	 * @param str
	 *              等式表达式
	 * @return 等号表达式 Map
	 */
	public static Map<String, String> getEqualMap(String str) {
		Map<String, String> equalMap = new HashMap<>();
		String[] searchedStrings = searchByRegex(str, "([^ ;,]+=[^ ;,]+)");
		for (String groupString : searchedStrings) {
			//这里不用 split 的原因是有可能等号后的值字符串中出现等号
			String[] equalStrings = new String[2];
			int equalCharIndex = groupString.indexOf("=");
			equalStrings[0] = groupString.substring(0, equalCharIndex);
			equalStrings[1] = groupString.substring(equalCharIndex + 1, groupString.length());
			if (equalStrings.length == 2) {
				String key = equalStrings[0];
				String value = equalStrings[1];
				if (value.startsWith("\"") && value.endsWith("\"")) {
					value = value.substring(1, value.length() - 1);
				}
				equalMap.put(key, value);
			}
		}
		return equalMap;
	}

	/**
	 * <pre>
	 * 获取HTTP 头属性里等式的值
	 * 	可以从字符串 Content-Type: multipart/form-data; boundary=ujjLiiJBznFt70fG1F4EUCkIupn7H4tzm
	 * 	直接解析出boundary的值.
	 * 	使用方法:getPerprotyEqualValue(packetMap,"Content-Type","boundary")获得ujjLiiJBznFt70fG1F4EUCkIupn7H4tzm
	 * </pre>
	 * @param propertyName   属性名
	 * @param valueName      属性值
	 * @return
	 */
	public static String getPerprotyEqualValue(Map<String, String> packetMap, String propertyName, String valueName) {
		String propertyValueObj = packetMap.get(propertyName);
		if (propertyValueObj == null) {
			return null;
		}
		String propertyValue = propertyValueObj.toString();
		Map<String, String> equalMap = getEqualMap(propertyValue);
		return equalMap.get(valueName);
	}

	/**
	 * ------------------------------------------------------------------------------------】
	 * 以上代码参考了voovan项目，不过为了适应需要，作了部分改动，感谢作者的贡献
	 * 项目地址： http://www.voovan.org/
	 * ------  end  ------
	 */
	/**
	 * @param args
	 * @author wchao
	 */
	public static void main(String[] args) {

	}

	/**
	 * 正则表达式查找,匹配的被提取出来做数组
	 * @param source 目标字符串
	 * @param regex 正则表达式
	 * @return  匹配的字符串数组
	 */
	public static String[] searchByRegex(String source, String regex) {
		if (source == null) {
			return null;
		}

		Pattern pattern = getCachedPattern(regex);
		Matcher matcher = pattern.matcher(source);
		ArrayList<String> result = new ArrayList<>();
		while (matcher.find()) {
			result.add(matcher.group());
		}
		return result.toArray(new String[0]);
	}

	/**
	 *
	 * @author wchao
	 */
	public HttpParseUtils() {
	}
}
