package cn.util.string;

import cn.constant.CharsetKit;
import cn.util.core.IsKit;
import cn.util.core.TypeKit;

import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

public class StringKit
{
	public static String[] objArrayToStrArray(Object[] objArray) 
	{
		if(IsKit.isNullOrEmpty(objArray)) {
			return new String[0];
		}
		return Arrays.asList(objArray).toArray(new String[0]);
	}

	
	/**
	 * 移除字符串中开始与结尾的字符"["和"]"
	 * 主要用于处理组件：el-select multiple 字段值格式:[1,2,3]
	 */
	public static String removeBracket(String str)
	{
		if(IsKit.isNullOrEmpty(str)) {
			return str;
		}
		if(str.contains(CharsetKit.SYMBOL_BRACKET_START)
				&& str.contains(CharsetKit.SYMBOL_BRACKET_END)
				&& str.length() > 2)//至少含有一个有效字符
		{
			return str.substring(1, str.length()-1);
		}
		return str;	
	}
	/**
	 * 截取字符串
	 * @param str   字符串
	 * @param start 开始
	 * @param end   结束
	 * @return 结果CharsetKit.NULLSTR;
	 */
	public static String substring(final String str, int start, int end) 
	{
		if (IsKit.isNullOrEmpty(str)) {
			return null;
		}
		if (end < 0) {
			end = str.length() + end;
		}
		if (start < 0) {
			start = str.length() + start;
		}
		if (end > str.length()) {
			end = str.length();
		}
		if (start > end) {
			return null;
		}
		if (start < 0) {
			start = 0;
		}
		if (end < 0) {
			end = 0;
		}
		return str.substring(start, end);
	}
	/**移除写库出错的字符 .api.sys.getDictData.sys_common_status*/
	public static String removeNoSQLChar(String source) 
	{
		if(IsKit.isNullOrEmpty(source)) {
			return source;	
		}
		//去掉字符串中的\字符
		source = source.replaceAll("\\\\","");
		//替换字符串中的/字符为.
		source = source.replaceAll("\\/",".");
		//去掉字符串中的'字符
		source = source.replaceAll("\'","");
		//去掉字符串中的"字符
		source = source.replaceAll("\"","");
		//替换字符串中的?字符为.
		source = source.replaceAll("\\?","");
		return source;
	}

	/**
	 * 去空格
	 */
	public static String trim(String str) {
		if (str == null) {
			return null;
		}
		return str.trim();
	}

	/**匹配正则表达式
	 * @param pattern 正则表达式
	 * @param str 待匹配的字符串
	 */
	public static boolean matches(String pattern, String str) {
		return Pattern.matches(pattern, str);
	}

	//去除字符串中的空格、回车、换行符、制表符
	public static String replaceBlank(String s)    
	{    
		Pattern p = Pattern.compile("\\s*|\t|\r|\n");    
		Matcher m = p.matcher(s);    
		return m.replaceAll("");    
	} 
	
	/**
	 * 截取字符串
	 *
	 * @param str   字符串
	 * @param start 开始
	 * @return 结果
	 */
	public static String substring(final String str, int start) {
		if (str == null) {
			return null;
		}

		if (start < 0) {
			start = str.length() + start;
		}

		if (start < 0) {
			start = 0;
		}
		if (start > str.length()) {
			return null;
		}

		return str.substring(start);
	}

	public static String getBlock(Object msg) {
		if (IsKit.isNull(msg)) {
			msg = "";
		}
		return "[" + msg + "]";
	}

	/**
	 * 比较两个字符串（大小写敏感）。
	 *
	 * <pre>
	 * equals(null, null)   = true
	 * equals(null, &quot;abc&quot;)  = false
	 * equals(&quot;abc&quot;, null)  = false
	 * equals(&quot;abc&quot;, &quot;abc&quot;) = true
	 * equals(&quot;abc&quot;, &quot;ABC&quot;) = false
	 * </pre>
	 *
	 * @param str1 要比较的字符串1
	 * @param str2 要比较的字符串2
	 * @return 如果两个字符串相同，或者都是{@code null}，则返回{@code true}
	 */
	public static boolean isEquals(CharSequence str1, CharSequence str2) {
		return isEquals(str1, str2, false);
	}

	/**
	 * 比较两个字符串是否相等，规则如下
	 * <ul>
	 *     <li>str1和str2都为{@code null}</li>
	 *     <li>忽略大小写使用{@link String#equalsIgnoreCase(String)}判断相等</li>
	 *     <li>不忽略大小写使用{@link String#contentEquals(CharSequence)}判断相等</li>
	 * </ul>
	 *
	 * @param str1       要比较的字符串1
	 * @param str2       要比较的字符串2
	 * @param ignoreCase 是否忽略大小写
	 * @return 如果两个字符串相同，或者都是{@code null}，则返回{@code true}
	 */
	public static boolean isEquals(CharSequence str1, CharSequence str2, boolean ignoreCase) {
		if (null == str1) {
			// 只有两个都为null才判断相等
			return str2 == null;
		}
		if (null == str2) {
			// 字符串2空，字符串1非空，直接false
			return false;
		}

		if (ignoreCase) {
			return str1.toString().equalsIgnoreCase(str2.toString());
		} else {
			return str1.toString().contentEquals(str2);
		}
	}

	/**
	 * 格式化字符串<br>
	 * 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
	 * 如果想输出 {} 使用 \\转义 { 即可，如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
	 * 例：<br>
	 * 通常使用：format("this is {} for {}", "a", "b") -> this is a for b<br>
	 * 转义{}： format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
	 * 转义\： format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
	 *
	 * @param strPattern 字符串模板
	 * @param argArray 参数列表
	 * @return 结果
	 */
	public static String format(final String strPattern, final Object... argArray)
	{
		if (IsKit.isEmpty(strPattern) || IsKit.isEmpty(argArray)){
			return strPattern;
		}
		final int strPatternLength = strPattern.length();

		// 初始化定义好的长度以获得更好的性能
		StringBuilder sbuf = new StringBuilder(strPatternLength + 50);

		int handledPosition = 0;
		int delimIndex;// 占位符所在位置
		for (int argIndex = 0; argIndex < argArray.length; argIndex++)
		{
			delimIndex = strPattern.indexOf(CharsetKit.EMPTY_JSON, handledPosition);
			if (delimIndex == -1){
				if (handledPosition == 0){
					return strPattern;
				}
				else{ // 字符串模板剩余部分不再包含占位符，加入剩余部分后返回结果
					sbuf.append(strPattern, handledPosition, strPatternLength);
					return sbuf.toString();
				}
			}
			else{
				if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == CharsetKit.C_BACKSLASH){
					if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == CharsetKit.C_BACKSLASH){
						// 转义符之前还有一个转义符，占位符依旧有效
						sbuf.append(strPattern, handledPosition, delimIndex - 1);
						sbuf.append(TypeKit.utf8ToStr(argArray[argIndex]));
						handledPosition = delimIndex + 2;
					}
					else{
						// 占位符被转义
						argIndex--;
						sbuf.append(strPattern, handledPosition, delimIndex - 1);
						sbuf.append(CharsetKit.C_DELIM_START);
						handledPosition = delimIndex + 1;
					}
				}
				else{
					// 正常占位符
					sbuf.append(strPattern, handledPosition, delimIndex);
					sbuf.append(TypeKit.utf8ToStr(argArray[argIndex]));
					handledPosition = delimIndex + 2;
				}
			}
		}
		// 加入最后一个占位符后所有的字符
		sbuf.append(strPattern, handledPosition, strPattern.length());
		return sbuf.toString();
	}

	public static boolean startsWithAny(final CharSequence string, final CharSequence... searchStrings) {
		if (IsKit.isEmpty(string) || ArrayUtils.isEmpty(searchStrings)) {
			return false;
		}
		for (final CharSequence searchString : searchStrings) {
			if (StringUtils.startsWith(string, searchString)) {
				return true;
			}
		}
		return false;
	}
}
