package com.zjrs.appcomm.utils;

import org.springframework.util.StringUtils;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class StringUtil {
	
	private static final String CUT_TAIL = "...";
	
	/**
	 * 对字符串按UTF8进行按字节的截断
	 * @param str 需要截断的字符串
	 * @param maxByteSize 需要截断的最大字节数
	 * @return 截断结果
	 */
	public static String substring(String str, int maxByteSize) {
		return substring(str, StandardCharsets.UTF_8, maxByteSize);
	}
	/**
	 * 对字符串进行按字节的截断
	 * @param str 需要截断的字符串
	 * @param charset 字节转换的字符集
	 * @param maxByteSize 需要截断的最大字节数
	 * @return 截断结果
	 */
	public static String substring(String str, Charset charset, int maxByteSize) {
		if (str == null) {
			return null;
		}
		byte[] strByte = str.getBytes(charset);
		if (strByte.length <= maxByteSize) {
			return str;
		}
		byte[] strNewByte = Arrays.copyOfRange(str.getBytes(), 0, maxByteSize);
		String newStr = null;
		for (int bLength = strNewByte.length; bLength >= 0; bLength--) {
			newStr = new String(strNewByte, 0, bLength, charset);
			if (str.startsWith(newStr)) {
				System.out.println(bLength);
				break;
			}
		}
		return newStr;
	}
	
	/**
	 * 将异常转换为字符串
	 * @param ex 需要转换为字符串的异常
	 * @return 转换结果
	 */
	public static String toString(Exception ex) {
		if (ex == null) {
			return null;
		}
		StringWriter sw = new StringWriter();
		try (PrintWriter pw = new PrintWriter(sw)) {
			ex.printStackTrace(pw);
		}
		return sw.toString();
	}
	
	/**
	 * 对字符串进行截断，当字符串超长需要截断时，将拼入“...”
	 * @param str 需要截断的字符串
	 * @param maxLength 需要截断的最大长度
	 * @return 截断结果
	 */
	public static String cutWithTail(String str, int maxLength) {
		if (str == null) {
			return null;
		} else if (str.length() > maxLength) {
			return str.substring(0, maxLength - CUT_TAIL.length()) + CUT_TAIL;
		} else {
			return str;
		}
	}
	
	/**
	 * 将异常进行截断，当字符串超长需要截断时，将拼入“...”
	 * @param ex 需要截断的异常
	 * @param maxLength 需要截断的最大长度
	 * @return 截断结果
	 */
	public static String cutWithTail(Exception ex, int maxLength) {
		return cutWithTail(toString(ex), maxLength);
	}
	
	/**
	 * 对字符串按UTF8进行按字节的截断，当字符串超长需要截断时，将拼入“...”
	 * @param str 需要截断的字符串
	 * @param maxByteSize 需要截断的最大字节数
	 * @return 截断结果
	 */
	public static String cutWithTailByByte(String str, int maxByteSize) {
		return cutWithTailByByte(str, StandardCharsets.UTF_8, maxByteSize);
	}
	
	/**
	 * 对字符串进行按字节的截断，当字符串超长需要截断时，将拼入“...”
	 * @param str 需要截断的字符串
	 * @param charset 字节转换的字符集
	 * @param maxByteSize 需要截断的最大字节数
	 * @return 截断结果
	 */
	public static String cutWithTailByByte(String str, Charset charset, int maxByteSize) {
		if (str == null) {
			return null;
		} else if (str.getBytes(charset).length > maxByteSize) {
			return substring(str, charset, maxByteSize - CUT_TAIL.getBytes(charset).length) + CUT_TAIL;
		} else {
			return str;
		}
	}
	
	/**
	 * 对异常按UTF8进行按字节的截断，当字符串超长需要截断时，将拼入“...”
	 * @param ex 需要截断的异常
	 * @param maxByteSize 需要截断的最大字节数
	 * @return 截断结果
	 */
	public static String cutWithTailByByte(Exception ex, int maxByteSize) {
		return cutWithTailByByte(ex, StandardCharsets.UTF_8, maxByteSize);
	}
	
	/**
	 * 对异常进行按字节的截断，当字符串超长需要截断时，将拼入“...”
	 * @param ex 需要截断的异常
	 * @param charset 字节转换的字符集
	 * @param maxByteSize 需要截断的最大字节数
	 * @return 截断结果
	 */
	public static String cutWithTailByByte(Exception ex, Charset charset, int maxByteSize) {
		return cutWithTailByByte(toString(ex), charset, maxByteSize);
	}
	
	/**
	 * 对字符串数组进行拼接
	 * @param array 需要拼接的字符串数组
	 * @param separator 拼接分隔符
	 * @return 对字符串数组进行拼接后的结果
	 */
	public static String join(String[] array, String separator) {
		StringBuilder sb = new StringBuilder();
		for (String str: array) {
			sb.append(separator).append(str);
		}
		if (sb.length() > 0) {
			return sb.substring(separator.length());
		}
		return "";
	}
	
	/**
	 * 不含正则的字符串分隔
	 * @param str 需要分割的字符串
	 * @param separator 分割符
	 * @param ignoreEmpty 是否忽略空串
	 * @return 字符串分隔结果
	 */
	public static List<String> split(String str, String separator, boolean ignoreEmpty) {
		if (StringUtils.isEmpty(separator)) {
			throw new IllegalArgumentException("separator不能为空");
		}
		List<String> strList = new ArrayList<String>();
		int i = 0;
		do {
			int index = str.indexOf(separator, i);
			if (index < 0) {
				String subStr = str.substring(i);
				if (!(ignoreEmpty && StringUtils.isEmpty(subStr))) {
					strList.add(subStr);
				}
				break;
			} else {
				String subStr = str.substring(i, index);
				if (!(ignoreEmpty && StringUtils.isEmpty(subStr))) {
					strList.add(subStr);
				}
				i = index + separator.length();
			}
		} while (true);
		return strList;
	}
	
}
