package com.house365.web.util;

import java.io.UnsupportedEncodingException;
import java.sql.Timestamp;

import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.apache.commons.lang3.StringUtils.split;

/**
 * 有关字符串的工具类
 *
 * @author huaqingchun
 * @version 1.0
 * @date
 */
public class StringUtils {

    private static final Logger LOGGER = LoggerFactory.getLogger(StringUtils.class);

    public static final String DEFAULT_EMPTY_STRING = "";

    public static final String DEFAULT_NULL_STRING = "null";

    /**
     * 判断字符串是否为空值(null, "", " ", "null")
     *
     * @param str
     * @return
     */
    public static boolean isEmpty(String str) {
        return str == null || DEFAULT_EMPTY_STRING.equals(str.trim()) || DEFAULT_NULL_STRING.equals(str.trim());
    }

    /**
     * 判断字符串是否不为空值
     *
     * @param str
     * @return
     */
    public static boolean isNotEmpty(String str) {
        return !isEmpty(str);
    }

    /**
     * 如果字符串为空值(null, "", " ", "null"),则将其转换为空串""
     *
     * @param str
     * @return
     */
    public static String notEmpty(String str) {
        if (isEmpty(str)) {
            return DEFAULT_EMPTY_STRING;
        }
        return str.trim();
    }

    /**
     * 如果字符串为空值(null, "", " ", "null"),则将其转换为默认值defaults
     *
     * @param str
     * @param defaults
     * @return
     */
    public static String defaultEmpty(String str, String defaults) {
        if (isEmpty(str)) {
            return defaults;
        } else {
            return str;
        }
    }

    /**
     * 判断输入字符是否为阿拉伯字母
     *
     * @param cs
     * @return
     */
    public static boolean isAlpha(CharSequence cs) {
        if (cs == null || cs.length() == 0) {
            return false;
        }
        int sz = cs.length();
        for (int i = 0; i < sz; i++) {
            if (Character.isLetter(cs.charAt(i)) == false) {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断字符是否为数字[0-9](注：不包含小数点.)
     *
     * @param cs
     * @return
     */
    public static boolean isNumeric(CharSequence cs) {
        if (cs == null || cs.length() == 0) {
            return false;
        }
        int sz = cs.length();
        for (int i = 0; i < sz; i++) {
            if (Character.isDigit(cs.charAt(i)) == false) {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断字符是否为数字(注：包含小数点.)
     *
     * @param str
     * @return
     */
    public static boolean isDigit(String str) {
        Pattern p = Pattern.compile("\\d+\\.?\\d*");
        Matcher m = p.matcher(str);
        return m.matches();
    }

    /**
     * 判断字符是否为字母或者数字[a-zA-Z0-9]
     *
     * @param cs
     * @return
     */
    public static boolean isAlphanumeric(CharSequence cs) {
        if (cs == null || cs.length() == 0) {
            return false;
        }
        int sz = cs.length();
        for (int i = 0; i < sz; i++) {
            if (Character.isLetterOrDigit(cs.charAt(i)) == false) {
                return false;
            }
        }
        return true;
    }

    /**
     * 在目标字符串targetStr左边补充字符appendChar,使得目标字符串的总长度达到length
     * (注：targetStr为null时返回null)
     *
     * @param targetStr
     * @param appendChar
     * @param length
     * @return
     */
    public static String lPad(String targetStr, char appendChar, int length) {
        if (targetStr == null) {
            return null;
        }
        int len = targetStr.length();
        while (len++ < length) {
            targetStr = appendChar + targetStr;
        }
        return targetStr;
    }

    /**
     * 在目标字符串targetStr右边补充字符appendChar,使得目标字符串的总长度达到length
     * (注：targetStr为null时返回null)
     *
     * @param targetStr
     * @param appendChar
     * @param length
     * @return
     */
    public static String rPad(String targetStr, char appendChar, int length) {
        if (targetStr == null) {
            return null;
        }
        int len = targetStr.length();
        while (len++ < length) {
            targetStr += appendChar;
        }
        return targetStr;
    }

    /**
     * 分别从目标字符串中的两端剔除需要剔除的字符串stripChars
     * <p>
     * <pre>
     * StringUtils.strip(null, *)          = null
     * StringUtils.strip("", *)            = ""
     * StringUtils.strip("abc", null)      = "abc"
     * StringUtils.strip("  abc", null)    = "abc"
     * StringUtils.strip("abc  ", null)    = "abc"
     * StringUtils.strip(" abc ", null)    = "abc"
     * StringUtils.strip("  abcyx", "xyz") = "  abc"
     * </pre>
     *
     * @param str
     * @param stripChars
     * @return
     */
    public static String strip(String str, String stripChars) {
        if (isEmpty(str)) {
            return str;
        }
        str = stripStart(str, stripChars);
        return stripEnd(str, stripChars);
    }

    /**
     * 从目标字符串中的起始端开始剔除需要剔除的字符串stripChars
     * <p>
     * <pre>
     * StringUtils.stripStart(null, *)          = null
     * StringUtils.stripStart("", *)            = ""
     * StringUtils.stripStart("abc", "")        = "abc"
     * StringUtils.stripStart("abc", null)      = "abc"
     * StringUtils.stripStart("  abc", null)    = "abc"
     * StringUtils.stripStart("abc  ", null)    = "abc  "
     * StringUtils.stripStart(" abc ", null)    = "abc "
     * StringUtils.stripStart("yxabc  ", "xyz") = "abc  "
     * </pre>
     *
     * @param str
     * @param stripChars
     * @return
     */
    public static String stripStart(String str, String stripChars) {
        int strLen;
        if (str == null || (strLen = str.length()) == 0) {
            return str;
        }
        int start = 0;
        if (stripChars == null) {
            while (start != strLen && Character.isWhitespace(str.charAt(start))) {
                start++;
            }
        } else if (stripChars.length() == 0) {
            return str;
        } else {
            while (start != strLen && stripChars.indexOf(str.charAt(start)) != -1) {
                start++;
            }
        }
        return str.substring(start);
    }

    /**
     * 从目标字符串中的末端开始剔除需要剔除的字符串stripChars
     * <p>
     * <pre>
     * StringUtils.stripEnd(null, *)          = null
     * StringUtils.stripEnd("", *)            = ""
     * StringUtils.stripEnd("abc", "")        = "abc"
     * StringUtils.stripEnd("abc", null)      = "abc"
     * StringUtils.stripEnd("  abc", null)    = "  abc"
     * StringUtils.stripEnd("abc  ", null)    = "abc"
     * StringUtils.stripEnd(" abc ", null)    = " abc"
     * StringUtils.stripEnd("  abcyx", "xyz") = "  abc"
     * StringUtils.stripEnd("120.00", ".0")   = "12"
     * </pre>
     *
     * @param str
     * @param stripChars
     * @return
     */
    public static String stripEnd(String str, String stripChars) {
        int end;
        if (str == null || (end = str.length()) == 0) {
            return str;
        }

        if (stripChars == null) {
            while (end != 0 && Character.isWhitespace(str.charAt(end - 1))) {
                end--;
            }
        } else if (stripChars.length() == 0) {
            return str;
        } else {
            while (end != 0 && stripChars.indexOf(str.charAt(end - 1)) != -1) {
                end--;
            }
        }
        return str.substring(0, end);
    }

    public static String trimAllWhitespace(String str) {
        if (str == null) {
            return null;
        }
        return str.replaceAll(" ", DEFAULT_EMPTY_STRING);
    }

    /**
     * 随机生成数字
     *
     * @param length
     * @return
     * @author
     */
    public static String getRandomNumber(int length) {
        String str = "0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; ++i) {
            int number = random.nextInt(9);
            sb.append(str.charAt(number));
        }
        return sb.toString();
    }

    /**
     * 随机生成字符
     *
     * @param length
     * @return
     * @author
     */
    public static String getRandomChars(int length) {
        String str = "0123456789ABCDEFGHIJKLMNPQRSTUVWXYZ";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; ++i) {
            int number = random.nextInt(35);
            sb.append(str.charAt(number));
        }
        return sb.toString();
    }

    /**
     * 判断字符串是否为空[null,""," "]
     *
     * @param str
     * @return
     * @author hzy
     */
    public static boolean isBlank(String str) {
        int strLen;
        if (str == null || (strLen = str.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if ((Character.isWhitespace(str.charAt(i)) == false)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断字符串是否非空[null,""," "]
     *
     * @param str
     * @return
     * @author hzy
     */
    public static boolean isNotBlank(String str) {
        return !isBlank(str);
    }

    /**
     * 处理String参数，如果str是空，则返回null
     *
     * @param str
     * @return
     * @author hzy
     */
    public static String ckStr(String str) {
        if (isNotBlank(str)) {
            return str.trim();
        }
        return null;
    }

    /**
     * 处理Integer参数，如果str是空，则返回null
     *
     * @param str
     * @return
     * @author hzy
     */
    public static Integer ckInt(String str) {
        if (isBlank(str)) {
            return null;
        }
        try {
            return Integer.parseInt(str.trim());
        } catch (NumberFormatException e) {
            LOGGER.error("String > Integer error, source[" + str + "]", e);
            return null;
        }
    }

    /**
     * 处理Timestamp参数，如果str是空，则返回null
     *
     * @param str
     * @return
     * @author hzy
     */
    public static Timestamp ckTime(String str) {
        if (isBlank(str) || str.indexOf("null") != -1) {
            return null;
        }
        try {
            return Timestamp.valueOf(str);
        } catch (IllegalArgumentException e) {
            LOGGER.error("String > Timestamp error, source[" + str + "]", e);
            return null;
        }
    }

    /**
     * MD5加密
     *
     * @param input
     * @return
     */
    public static String md5Encrypt(String input) {
        return DigestUtils.md5Hex("@com.house365$anjd_" + input);
    }

    /**
     * 替换换行 tab 回车
     *
     * @param str
     * @return
     */
    public static String replaceBlank(String str) {
        String dest = "";
        if (str != null) {
            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
            Matcher m = p.matcher(str);
            dest = m.replaceAll("");
        }
        return dest;
    }

    // 过滤特殊字符
    public static String StringFilter(String str) {
        // 只允许字母和数字
        // String   regEx  =  "[^a-zA-Z0-9]";
        // 清除掉所有特殊字符
        String regEx = "[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.replaceAll(" ").trim();
    }

    public static String decodeUnicode(final String dataStr) {
        int start = 0;
        int end = 0;
        final StringBuffer buffer = new StringBuffer();
        while (start > -1) {
            end = dataStr.indexOf("\\u", start + 2);
            String charStr = "";
            if (end == -1) {
                charStr = dataStr.substring(start + 2, dataStr.length());
            } else {
                charStr = dataStr.substring(start + 2, end);
            }
            char letter = (char) Integer.parseInt(charStr, 16); // 16进制parse整形字符串。
            buffer.append(new Character(letter).toString());
            start = end;
        }
        return buffer.toString();
    }

    /**
     * 转换为JS获取对象值，生成三目运算返回结果
     *
     * @param objectString 对象串
     *                     例如：row.user.id
     *                     返回：!row?'':!row.user?'':!row.user.id?'':row.user.id
     */
    public static String jsGetVal(String objectString) {
        StringBuilder result = new StringBuilder();
        StringBuilder val = new StringBuilder();
        String[] vals = split(objectString, ".");
        for (int i = 0; i < vals.length; i++) {
            val.append("." + vals[i]);
            result.append("!" + (val.substring(1)) + "?'':");
        }
        result.append(val.substring(1));
        return result.toString();
    }


    /**
     * 缩略字符串（不区分中英文字符）
     *
     * @param str    目标字符串
     * @param length 截取长度
     * @return
     */
    public static String abbr(String str, int length) {
        if (str == null) {
            return "";
        }
        try {
            StringBuilder sb = new StringBuilder();
            int currentLength = 0;
            for (char c : replaceHtml(StringEscapeUtils.unescapeHtml4(str)).toCharArray()) {
                currentLength += String.valueOf(c).getBytes("GBK").length;
                if (currentLength <= length - 3) {
                    sb.append(c);
                } else {
                    sb.append("...");
                    break;
                }
            }
            return sb.toString();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 替换掉HTML标签方法
     */
    public static String replaceHtml(String html) {
        if (isBlank(html)) {
            return "";
        }
        String regEx = "<.+?>";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(html);
        String s = m.replaceAll("");
        return s;
    }


}
