package com.pcloud.common.utils.string;

import java.io.UnsupportedEncodingException;
import java.util.Comparator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 字符串排序类
 * @author PENG
 * @date 2018/4/3
 */
public class StringComparator implements Comparator<String> {

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

    /**
     * 是否大小写不敏感
     */
    private Boolean caseInsensitive = false;

    public StringComparator() {
    }

    public StringComparator(Boolean caseInsensitive) {
        this.caseInsensitive = caseInsensitive;
    }

    @Override
    public int compare(String str1, String str2) {
        // 特殊情形，str有一个为空的情况
        if (null == str1) {
            // 都为空，认为相等
            if (null == str2) {
                return 0;
            } else {
                return -1;
            }
        } else if (null == str2) {
            return 1;
        } else if (caseInsensitive) {
            str1 = str1.toLowerCase();
            str2 = str2.toLowerCase();
        }
        // 比较
        for (int i = 0; i < str1.length(); i++) {
            if (i == str1.length() && i < str2.length()) {
                return -1;
            } else if (i == str2.length() && i < str1.length()) {
                return 1;
            }
            char ch1 = str1.charAt(i);
            char ch2 = str2.charAt(i);
            boolean isCh1Num = ch1 >= '0' && ch1 <= '9';
            boolean isCh2Num = ch2 >= '0' && ch2 <= '9';
            if (isCh1Num && isCh2Num) {
                long i1 = getNumber(str1.substring(i));
                long i2 = getNumber(str2.substring(i));
                if (i1 != i2) {
                    return i1 > i2 ? 1 : -1;
                }
            } else if (isCh1Num) {
                return -1;
            } else if (isCh2Num) {
                return 1;
            } else if (ch1 != ch2) {
                String hexStr1 = getHexString(str1,"GBK");
                String hexStr2 = getHexString(str2,"GBK");
                return hexStr1.compareTo(hexStr2);
            }
        }
        return 0;
    }

    private static String getHexString(String str, String charset) {
        byte[] bytes = null;
        StringBuilder stringBuilder = new StringBuilder();
        try {
            bytes = str.getBytes(charset);
        } catch (UnsupportedEncodingException e) {
            LOGGER.error("字符转码失败:" + e.getMessage(), e);
        }
        if (null != bytes) {
            for (byte b : bytes) {
                stringBuilder.append(Integer.toHexString(b & 0xFF));
            }
        }
        return stringBuilder.toString();
    }

    private long getNumber(String str) {
        long num = Long.MAX_VALUE;
        int bits = 0;
        for (int i = 0; i < str.length(); i++) {
            if (str.charAt(i) >= '0' && str.charAt(i) <= '9') {
                bits++;
            } else {
                break;
            }
        }
        if (bits > 0) {
            num = Long.parseLong(str.substring(0, bits));
        }
        return num;
    }
}
