package com.brilliance.mda.runtime.mda.util;

import com.brilliance.mda.runtime.mda.IStream;
import com.brilliance.isc.common.context.AppEnv;
import com.brilliance.isc.utils.SpringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;

import static com.brilliance.mda.runtime.mda.Constants.NO_NAN;
import static com.brilliance.mda.runtime.mda.Constants.NULLSTR;

public abstract class Strings {

    private static final Logger log = LoggerFactory.getLogger(Strings.class);

    public static boolean isEmpty(Object obj){
        return !notEmpty(obj);
    }

    public static boolean notEmpty(Object obj){
        return obj !=null && !"".equals(obj.toString());
    }

    public static Integer toInt(Object obj){
        if(obj instanceof Integer){
            return (Integer) obj;
        }
        return notEmpty(obj) ? Integer.valueOf(obj.toString()) : null;
    }

//    public static String catPath(String path, String subPath) {
//        if (Strings.notEmpty(subPath)) {
//            subPath = subPath.toLowerCase();
//        }
//        File file = new File(new File(MdaEnv.getRootPath() + "/" + path), subPath);
//        if (!file.exists() || file.isDirectory()) {
//            return "";
//        }
//        return file.getAbsolutePath();
//    }

    public static String rpad(String str,int len,char c){
        StringBuilder builder = new StringBuilder();
        for (int i = 0 ;i < str.length() ;i++) {
            builder.append(str.charAt(i));
        }
        for (int i = builder.length(); i < len; i++) {
            builder.append(c);
        }
        return builder.toString();
    }

    public static String lpad(String str,int len,char c){
        StringBuilder builder = new StringBuilder();
        for (int i = 0 ;i < len-str.length() ; i++) {
            builder.append(c);
        }
        for (int i=len-str.length(),j=0; i <len; i++,j++) {
            builder.append(str.charAt(j));
        }
        return builder.toString();
    }

    public static String convertPrefix(String path){
        if (path == null){
            return path;
        }
        if (path.startsWith("CLIENT:") || path.startsWith("SERVER:")){
            path = path.substring(path.indexOf(":") + 1);
        }
        if(!path.endsWith(Files.separator)){
            return path + Files.separator;
        }
        return path;
    }

    public static String getLine(IStream stream, int idx) {
        if(stream == null)
            return NULLSTR;
        if(idx <= stream.countLines() && idx>0)
            return stream.getLine(idx);
        return NULLSTR;
    }
    public static String getLine(IStream stream, double idx) {
        return getLine(stream, (int)idx);
    }
    public static String getLine(String block, int line) {
        if(isEmpty(block))
            return NULLSTR;
        String[] arr = block.split("[\\r\\n]{1,2}");
        if(line<= arr.length)
            return arr[line-1];
        return NULLSTR;
    }
    public static String getLine(String block, double line) {
        return getLine(block, (int)line);
    }

    public static String trimEnd(String str, String endStr) {
        while (str.endsWith(endStr)) {
            str = str.substring(0, str.lastIndexOf(endStr));
        }
        return str;

    }

    public static String leftTrim(String str) {
        int pos = 0;
        for (int i=0; i < str.length(); i++) {
            if (str.charAt(i) != ' ')
            {
                pos = i;
                break;
            }
        }
        if (pos == 0) return str;
        if (pos + 1 == str.length())
            return NULLSTR;
        return str.substring(pos);
    }

    public static String trim(Object obj) {
        return obj == null ? NULLSTR : obj.toString().trim();
    }

    public static String toUpper(String text) {
        return text == null ? NULLSTR : text.toUpperCase();
    }

    public static String toLower(String text) {
        return text == null ? NULLSTR : text.toLowerCase();
    }

    //返回子串位置，TD中起始索引从1开始，返回零表示找不到字串
    public static int pos(String str, String sub) {
        if (str == null) {
            return 0;
        }
        if (sub == null) {
            return 0;
        }
        if("".equals(sub)) {
            return 0;
        }
        int p = str.indexOf(sub);
        if(!byByte)
            return str.indexOf(sub)+1;
        if(p<=0)
            return p+1;
        String tmp = str.substring(0,p);
        try {
            return tmp.getBytes("GBK").length+1;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return 0;
        }
    }
    public static int pos(IStream str, String sub) {
        if(str == null || str.isEmpty()||sub==null||sub.length() ==0){
            return 0;
        }
        int i = 1;
        for (String row : str.getRows()){
            if(row.indexOf(sub) >= -1){
                return i;
            }
            i++;
        }
        return 0;
    }

    private static boolean byByte = true;
    //截取字符串，TD中起始索引从1开始
    public static String mid(String str, int p) {
        if(byByte){
            return cutBytes(str,p,-1);
        }
        if (str == null) return NULLSTR;
        if (str.length() < p) return NULLSTR;
        return str.substring(p == 0 ? 0 : --p);
    }

    public static String mid(String str, int p, int l) {
        if(byByte){
            return cutBytes(str,p,l);
        }
        if (MdaUtils.isEmpty(str) || str.length() < p) {
            if(l == 0) {
                return NULLSTR;
            }else{
                return String.format("%" + l + "s", NULLSTR);
            }

        }
        if (l < 0)
            return mid(str,p);
        if(p == 0){
            p=1;
        }
        if (str.length() < p + l) {
            String temp = str.substring(--p);
            return String.format("%-" + l + "s", temp);
        }
        //对截取联行号电话的字段（固定截取16位）做处理
//        if(p == 16){
//            String result = "";
//            try {
//                result = MdaUtilsEx.cutStringByByte(str , --p, p + l);
//            } catch (IOException e) {
//                e.printStackTrace();
//            }finally{
//                return result;
//            }
//        }
        return str.substring(--p, p + l);
    }

    public static String cutBytes(String str,int start,int len){
        if(len == 0){
            return NULLSTR;
        }
        if(str == null) {
            str = NULLSTR;
        }
        if(start == 0)
            start = 1;
        try {
            start--;
            byte[] buf = str.getBytes("GBK");
            if(start >= buf.length) {
                if (len < 0) return "";
                return com.google.common.base.Strings.repeat(" ", len);
            }
            byte[] dest;
            if(len < 0 || start+len <= buf.length){
                if(len < 0)
                    len = buf.length-start;
                dest = new byte[len];
                System.arraycopy(buf,start,dest,0,len);
            }else{
                dest = new byte[len];
                byte fillValue = 32;    //空格
                Arrays.fill(dest, fillValue);
                System.arraycopy(buf,start,dest,0,buf.length - start);
            }
            return new String(dest,"GBK");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 使用GBK编码表进行字符串的截取，一个英文字符对应码表一个正数，一个汉字对应两个负数
     **/
    public static String cutStringByByte(String str, int start ,int len)
            throws IOException {
        byte[] buf = str.getBytes("gbk");
        int count = 0;
        for (int x = len - 1; x >= start; x--) {
            if (buf[x] < 0) {
                count++;
            } else {
                break;
            }
        }
        if (count % 2 == 0) {
            return new String(buf, 0, len, "gbk");
        } else {
            return new String(buf, 0, len - 1, "gbk");
        }
    }

    /**
     * 以字节计数的长度
     *
     * @param str
     * @return
     */
    public static int len(String str) {
        if (str == null) return 0;
        int len = str.length() - 1;
        if (!str.trim().equals("")){
            while(str.charAt(len) == ' '){
                len--;
            }
        }
        str = str.substring(0, len + 1);
        if(byByte){
            return str.getBytes(Charset.forName("GBK")).length;
        }
        return str.length();
    }

    //从消息系统中检索消息，参数M是要检索消息的标识符。如果所检索的消息文本中包含有“$n”，那么可选参数就给“$n”赋值。
    public static String getText(String format, Object... args) {
        return formatText(format, args);
    }

    public static String formatText(String format, Object... args) {
        if (format == null) return NULLSTR;
        if (args == null || args.length == 0)
            return format;
        for (int i = 0; i < args.length; i++) {
            String key = "\\$" + (i + 1);
            String arg = args[i] == null ? "null" : args[i].toString();
            arg = Matcher.quoteReplacement(arg);
            format = format.replaceAll(key, arg);
        }
        return format;
    }

    public static String getAbsPath(String path) {
        if (path == null) return "";
        File f = new File(SpringUtils.getBean(AppEnv.class).getRootPath(), path);
        if(!f.exists()){
            f.mkdirs();
        }
        if (f.isDirectory()) {
            return f.getAbsolutePath() + File.separator;
        } else {
            return f.getAbsolutePath();
        }
    }

    //前台方法空实现
    public static String convertBlock(String block, int convtype, int lines, int linelength) {
        return block;
    }

    public static String convertBlock(String block, int convtype, int lines) {
        return block;
    }

    public static String convertBlock(String argBlock, int i) {
        switch (i) {
            case 0:
                break;
            case 11:
                argBlock = argBlock.replace("<", "&lt");
                argBlock = argBlock.replace(">", "&gt");
                argBlock = argBlock.replace("&", "&amp");
                break;
            case 21:
                break;
            default:
                break;
        }
        return argBlock;
    }

    public static String[] splitArgumentsString(String argsString) {
        if (argsString == null)
            return null;
        List<String> argList = new ArrayList<>();
        boolean strflag = false; //是否处于字符串中
        boolean charflag = false;
        int segPos = 0;
        for (int i = 0; i < argsString.length(); i++) {
            char c = argsString.charAt(i);
            if(c == '"'){
                if(!charflag){
                    strflag = !strflag;
                }
            }
            else if(c == '\''){
                if(!strflag) {
                    charflag = !charflag;
                }
            }
            else if(c == '\\'){ //转义符号
                //字符串模式下忽略下一个字符
                if(strflag || charflag) {
                    i++;
                }
            }
            else if(c == ','){
                if(!strflag && !charflag){
                    argList.add(argsString.substring(segPos,i));
                    segPos = i+1;
                }
            }
            //末尾一个
            if(i == argsString.length() - 1){
                argList.add(argsString.substring(segPos));
            }
        }
        return argList.toArray(new String[0]);
    }

    public static void setLine(String block, int i, String s2) {
    }

    public static int searchBlock(IStream s1, String s2) {
        return s1.getRows().indexOf(s2) + 1;
    }

    public static int searchBlock(String valCur, String inCur) {
        return valCur.indexOf(inCur) + 1;
    }




    public static final int parseInt(Object value) {
        try {
            if(isEmpty(value)){
                return 0;
            }
            if ((value instanceof String))
                return new BigDecimal(((String) value).trim()).intValue();
            if (value instanceof BigDecimal)
                return ((BigDecimal)value).intValue();
            return new BigDecimal(value.toString()).intValue();
        } catch (Exception e) {
            log.warn(String.format("value:[%s] not a int",value),e);
        }
        return 0;
    }

    public static final BigDecimal parseDecimal(Object value) {

        try {

            if ((value instanceof String)){
                if(isEmpty(value)){
                    return BigDecimal.ZERO;
                }
                return new BigDecimal((String) value);
            }

            return new BigDecimal(value.toString());
        } catch (Exception e) {
            log.warn(String.format("value:[%s] not a number",value));
        }
        return BigDecimal.ZERO;
    }

    public static final Boolean parseBoolean(Object value, Boolean defaultValue) {
        if (value == null)
            return defaultValue;
        try {

            if ((value instanceof Boolean))
                return (Boolean) value;
            return Boolean.valueOf(Boolean.parseBoolean(value.toString()));
        } catch (Exception e) {
        }
        return defaultValue;
    }

    public static final Date parseDate(String val) {
        if (val == null || val.length() == 0){
            return null;
        }
        if (val.indexOf("/") >= 0){
            String[] split = val.split("/");
            if (split.length >= 3){
                val = split[2] + "-" + split[1] + "-" + split[0];
            }else{
                return null;
            }
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = simpleDateFormat.parse(val);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    public static final Date parseDate(Object value, String pattern) {
        if (value == null)
            return null;
        try {
            String v = (value instanceof String) ? (String) value : value.toString();
            SimpleDateFormat format = new SimpleDateFormat(pattern);
            return format.parse(v);
        } catch (Exception e) {
        }
        return null;
    }

    public static String blockFill(String res) {
        return res;
    }


    public static String converttoXMLStringPublic(String str) {
        if(str==null){
            return "";
        }
        str= str.replaceAll("&","&amp;");
        str= str.replaceAll("<","&lt;");
        str= str.replaceAll(">","&gt;");
        str= str.replaceAll("\"","&quot;");
        str= str.replaceAll("\'","&apos;");

        return str;
    }

}