package com.wayne.www.waynelib.util;

import android.content.Context;
import android.os.Build;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.WindowManager;

import com.wayne.www.waynelib.common.AutoResetEvent;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okio.BufferedSink;
import okio.Okio;
import okio.Sink;


/**
 * Created by Think on 4/19/2016.
 */
public class Util {
    static String LOG_TAG = "com.wayne.ui.Util";
    private static Logger fileLogger = LoggerFactory.getLogger(Util.class);

    public static boolean isEmulator() {
        return Build.FINGERPRINT.startsWith("generic")
                || Build.FINGERPRINT.startsWith("unknown")
                || Build.MODEL.contains("google_sdk")
                || Build.MODEL.contains("Emulator")
                || Build.MODEL.contains("Android SDK built for x86")
                || Build.MANUFACTURER.contains("Genymotion")
                || (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
                || "google_sdk".equals(Build.PRODUCT);
    }

    final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();

    public static String bytesToHexString(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }

    public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];

        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
        }

        return data;
    }

    public static byte[] concat(byte[] first, byte[] second) {
        byte[] result = new byte[first.length + second.length];
        for (int i = 0; i < first.length; i++) {
            result[i] = first[i];
        }

        for (int i = 0; i < second.length; i++) {
            result[first.length + i] = second[i];
        }

        return result;
    }

    public static int byteArray4ToInt(byte[] b) {
        if (b == null || b.length != 4) return -1;
        int result = (b[3] & 0xFF) + ((b[2] & 0xFF) << 8) + ((b[1] & 0xFF) << 16) + ((b[0] & 0xFF) << 24);
//        Log.v(LOG_TAG, "byteArray4ToInt, result is " + result
//                + ", byte[3]: " + b[3] + "(" + (b[3] & 0xFF) + ")"
//                + ", byte[2]: " + b[2] + "(" + ((b[2] & 0xFF) << 8) + ")"
//                + ", byte[1]: " + b[1] + "(" + ((b[1] & 0xFF) << 16) + ")"
//                + ", byte[0]: " + b[0] + "(" + ((b[0] & 0xFF) << 24) + ")");
        return result;
    }

    /* byte[0] is the low digit. */
    public static byte[] intToByteArray4(int a) {
        byte[] ret = new byte[4];
        ret[0] = (byte) (a & 0xFF);
        ret[1] = (byte) ((a >> 8) & 0xFF);
        ret[2] = (byte) ((a >> 16) & 0xFF);
        ret[3] = (byte) ((a >> 24) & 0xFF);
        return ret;
    }

    /* byte[0] is the high digit. */
    public static byte[] intToByteArray4Reverse(int a) {
        byte[] ret = new byte[4];
        ret[0] = (byte) ((a >> 24) & 0xFF);
        ret[1] = (byte) ((a >> 16) & 0xFF);
        ret[2] = (byte) ((a >> 8) & 0xFF);
        ret[3] = (byte) (a & 0xFF);
        return ret;
    }

    /**
     * 字符串编码成Unicode编码
     */
    public static String encode(String src) throws Exception {
        char c;
        StringBuilder str = new StringBuilder();
        int intAsc;
        String strHex;
        for (int i = 0; i < src.length(); i++) {
            c = src.charAt(i);
            intAsc = (int) c;
            strHex = Integer.toHexString(intAsc);
            if (intAsc > 128)
                str.append("\\u" + strHex);
            else
                str.append("\\u00" + strHex); // 低位在前面补00
        }
        return str.toString();
    }

    /**
     * Unicode解码成字符串
     *
     * @param src
     * @return
     */
    public static String decode(String src) {
        int t = src.length() / 6;
        StringBuilder str = new StringBuilder();
        for (int i = 0; i < t; i++) {
            String s = src.substring(i * 6, (i + 1) * 6); // 每6位描述一个字节
            // 高位需要补上00再转
            String s1 = s.substring(2, 4) + "00";
            // 低位直接转
            String s2 = s.substring(4);
            // 将16进制的string转为int
            int n = Integer.valueOf(s1, 16) + Integer.valueOf(s2, 16);
            // 将int转换为字符
            char[] chars = Character.toChars(n);
            str.append(new String(chars));
        }
        return str.toString();
    }

    /* byte[0] is the low digit. */
    public static byte[] stringToBytesWith4BytesLenAhead(String value) {
        byte[] len = intToByteArray4(value.length());
        byte[] body = value.getBytes();
        byte[] result = new byte[4 + body.length];
        for (int i = 0; i < result.length; i++) {
            if (i <= 3)
                result[i] = len[i];
            else
                result[i] = body[i - 4];
        }

        return result;
    }

    /**
     * @param format "yyyy-MM-dd HH:mm:ss", or "yyyy-MM-dd"
     * @return
     */
    public static String getCurrentTimeString(String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        String currentDateAndTime = sdf.format(new Date());
        return currentDateAndTime;
    }

    public static String toString(Document document) {
        String result = null;
        if (document != null) {
            StringWriter strWtr = new StringWriter();
            StreamResult strResult = new StreamResult(strWtr);
            TransformerFactory tfac = TransformerFactory.newInstance();
            try {
                Transformer t = tfac.newTransformer();
                t.setOutputProperty(OutputKeys.ENCODING, "utf-8");
                t.setOutputProperty(OutputKeys.INDENT, "yes");
                t.setOutputProperty(OutputKeys.METHOD, "xml"); // xml, html,// text
                t.setOutputProperty(
                        "{http://xml.apache.org/xslt}indent-amount", "4");
                t.transform(new DOMSource(document.getDocumentElement()),
                        strResult);
            } catch (Exception e) {
                System.err.println("XML.toString(Document): " + e);
            }
            result = strResult.getWriter().toString();
        }

        return result;
    }

    public static String convertJavaDateToXmlTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        /* format time */
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf2 = new SimpleDateFormat("HH:mm:ss");
        StringBuffer buff = new StringBuffer();
        buff.append(sdf1.format(date));
        buff.append('T');
        buff.append(sdf2.format(date));
        /* calculate time zone */
        int offset = calendar.get(calendar.ZONE_OFFSET) / (1000 * 60);
        if (offset < 0) {
            buff.append('-');
            offset *= -1;
        } else {
            buff.append('+');
        }
        String s1 = String.valueOf(offset / 60);
        for (int i = s1.length(); i < 2; i++) {
            buff.append('0');
        }
        buff.append(s1);
        buff.append(':');
        String s2 = String.valueOf(offset % 60);
        for (int i = s2.length(); i < 2; i++) {
            buff.append('0');
        }
        buff.append(s2);
        System.out.println("in DateUtils: " + buff.toString());
        return buff.toString();
    }

    /* sample result is like: 2016-04-26T09:41:44 */
    public static String getNowTimeWithXmlFormat() {
        //SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSZ");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
        String result = sdf.format(new Date());
        return result;
    }

    /* sample result is like: 2016-04-26 09:41:44 */
    public static String getNowTime() {
        //SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSZ");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String result = sdf.format(new Date());
        return result;
    }

    /**
     * input string like: 2016-04-29 11:20:16, and convert it to java.util.Date
     *
     * @param dateString   like: 2016-04-29 11:20:16 or 1983-10-04T08:18:28
     * @param formatString like: yyyy-MM-dd HH:mm:ss   or  yyyy-MM-dd'T'HH:mm:ss
     * @return for retrieve the year, month, day and etc. via return result(Calendar type),
     * use code like: result.get(Calendar.YEAR), result.get(Calendar.MONTH), NOTE, the MONTH is 0-based,
     * so return int 0 indicates month January, int 1 indicates month February.
     */
    public static Calendar convertTimeStrToJavaDate(String dateString, String formatString) {
        //SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSZ");
        SimpleDateFormat sdf = new SimpleDateFormat(formatString);
        Calendar calendar = new GregorianCalendar();

        try {
            Date noName = sdf.parse(dateString);
            calendar.setTime(noName);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return calendar;
    }

    public static String convertCalendarToString(Calendar calendar) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(calendar.getTime());
    }

    public static String setGravity(String s, String gravity, int totalWidth, char paddingWith) {
        int strLen = s.length();
        if (strLen >= totalWidth)
            return s;

        if (gravity.equalsIgnoreCase("right"))
            return pad(s, "left", totalWidth, paddingWith);
        else if (gravity.equalsIgnoreCase("left"))
            return pad(s, "right", totalWidth, paddingWith);
        else {
            return pad(s, "left", strLen + (totalWidth - strLen) / 2, paddingWith);
        }
    }

    public static int toUnsignedInt(byte x) {
        return ((int) x) & 0xff;
    }

    /*direction: "left", "right"*/
    public static String pad(String s, String direction, int totalWidth, char paddingWith) {
        if (s.length() >= totalWidth) return s;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < totalWidth - s.length(); i++) {
            sb.append(paddingWith);
        }

        if (direction.equalsIgnoreCase("right"))
            return s + sb.toString();
        else if (direction.equalsIgnoreCase("left"))
            return sb.toString() + s;
        return "";
    }

    /* 0003 will equal with 3, 03 will equal with 3*/
    public static boolean isRequestIdEqual(String lid, String rid) {
        int zeroDigitCount = 0;
        for (int i = 0; i < lid.length(); i++) {
            if (Character.compare(lid.charAt(i), '0') == 0) {
                zeroDigitCount++;
            }
        }

        String newLid = lid.substring(zeroDigitCount);

        zeroDigitCount = 0;
        for (int i = 0; i < rid.length(); i++) {
            if (Character.compare(rid.charAt(i), '0') == 0) {
                zeroDigitCount++;
            }
        }

        String newRid = rid.substring(zeroDigitCount);
        return newLid.equals(newRid);
    }

    public static String floatTo2DigitsString(float value) {
        DecimalFormat myFormatter = new DecimalFormat("##0.00");
        return myFormatter.format(value);
    }

    public static String doubleTo2DigitsString(double value) {
        DecimalFormat myFormatter = new DecimalFormat("##.##");
        return myFormatter.format(value);
    }

    /**
     * Returns a {@code List} of the specified portion of this {@code List} from the given start
     * index to the end index minus one. The returned {@code List} is backed by this
     * {@code List} so changes to it are reflected by the other.
     *
     * @param fromIndex the index at which to start the sublist.  inclusive.
     * @param toIndex   the index one past the end of the sublist.  exclusive.
     * @return a list of a portion of this {@code List}.
     */
    public static <T> List<T> safeSubList(List<T> list, int fromIndex, int toIndex) {
        int size = list.size();
        if (fromIndex >= size || toIndex <= 0 || fromIndex >= toIndex) {
            return Collections.emptyList();
        }

        fromIndex = Math.max(0, fromIndex);
        toIndex = Math.min(size, toIndex);

        return list.subList(fromIndex, toIndex);
    }

    public static <T> List<T> safeSubList(List<T> list, int fromIndex) {
        int toIndex = list.size() - 1;
        int size = list.size();
        if (fromIndex >= size || toIndex <= 0 || fromIndex >= toIndex) {
            return Collections.emptyList();
        }

        fromIndex = Math.max(0, fromIndex);
        toIndex = Math.min(size, toIndex);

        return list.subList(fromIndex, toIndex);
    }

    public static byte[] toPrimitives(Byte[] bytes) {
        byte[] noName = new byte[bytes.length];
        for (int i = 0; i < bytes.length; i++) {
            noName[i] = bytes[i];
        }

        return noName;
    }

    public static Byte[] fromPrimitives(byte[] bytes) {
        Byte[] noName = new Byte[bytes.length];
        for (int i = 0; i < bytes.length; i++) {
            noName[i] = new Byte(bytes[i]);
        }

        return noName;
    }

    /**
     * auto zip, and then upload.
     *
     * @param serverIp
     * @param ftpServerSubFolder without and slash, just the plain folder name is good.
     */
    public static void uploadTxtLogFileToServer(String serverIp, String ftpServerSubFolder, String[] simpleSearchPatterns) {
        FTPClient con;
        File targetFolder = new File("/data/data/com.wayne.www.smartscreen/log");
        try {
            con = new FTPClient();
            //con.connect("116.62.148.205");
            con.connect(serverIp, 22);
            if (con.login("androidPos", "111111")) {
                con.enterLocalPassiveMode(); // important!
                con.setFileType(FTP.BINARY_FILE_TYPE);
//                con.setFileTransferMode(FTP.ASCII_FILE_TYPE);
                File[] logFiles = targetFolder.listFiles();
                if (logFiles != null) {
                    for (int i = 0; i < logFiles.length; i++) {
                        Boolean matched = false;
                        for (int s = 0; s < simpleSearchPatterns.length; s++) {
                            if (logFiles[i].getName().contains(simpleSearchPatterns[s])
                                    // ONLY check .txt file
                                    && logFiles[i].getName().endsWith(".txt")) {
                                matched = true;
                                break;
                            }
                        }

                        if (!matched) continue;
                        fileLogger.debug("File: " + logFiles[i].getName() + " is selected for uploading...");
                        String zipTo_ShortFileName = logFiles[i].getName() + ".zip";
                        String zipTo_FullFileName = logFiles[i].getParent() + "/" + logFiles[i].getName() + ".zip";
                        fileLogger.debug("zip FileName will be set to: " + zipTo_FullFileName);
                        zip(logFiles[i].getPath(), zipTo_FullFileName);
                        FileInputStream in = new FileInputStream(zipTo_FullFileName);
                        // hardcode the default folder for no SN device
                        if (ftpServerSubFolder == null) ftpServerSubFolder = "Unknown_No_SN_Device";
                        fileLogger.info("Log file: " + zipTo_FullFileName + " is uploading to " + ftpServerSubFolder);
                        con.makeDirectory(ftpServerSubFolder);
                        boolean result = con.storeFile("\\" + ftpServerSubFolder + "\\" + zipTo_ShortFileName, in);
                        fileLogger.info("Log file: " + zipTo_ShortFileName + " is uploaded with result: " + result);
                        in.close();
                    }
                }

                con.logout();
                con.disconnect();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static int ZIP_BUFFER_SIZE = 1024;

    public static void zip(String sourceFileFullPath, String descFileFullPath) throws IOException {
        BufferedInputStream origin;
        ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(descFileFullPath)));
        try {
            byte data[] = new byte[ZIP_BUFFER_SIZE];
            FileInputStream fi = new FileInputStream(sourceFileFullPath);
            origin = new BufferedInputStream(fi, ZIP_BUFFER_SIZE);
            try {
                ZipEntry entry = new ZipEntry(sourceFileFullPath);
                out.putNextEntry(entry);
                int count;
                while ((count = origin.read(data, 0, ZIP_BUFFER_SIZE)) != -1) {
                    out.write(data, 0, count);
                }

                out.closeEntry();
            } finally {
                origin.close();
            }
        } finally {
            out.close();
        }
    }

    public static int getScreenWidth(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        DisplayMetrics metrics = new DisplayMetrics();
        display.getMetrics(metrics);
        return metrics.widthPixels;
    }

    public static int getScreenHeight(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        DisplayMetrics metrics = new DisplayMetrics();
        display.getMetrics(metrics);
        return metrics.heightPixels;
    }

    /**
     * 复制单个文件
     *
     * @param oldPath String 原文件路径 如：c:/fqf.txt
     * @param newPath String 复制后路径 如：f:/fqf.txt
     * @return boolean
     */
    public static void copyFile(String oldPath, String newPath) {
        try {
            int bytesum = 0;
            int byteread = 0;
            File oldfile = new File(oldPath);
            if (oldfile.exists()) { //文件存在时
                InputStream inStream = new FileInputStream(oldPath); //读入原文件
                FileOutputStream fs = new FileOutputStream(newPath);
                byte[] buffer = new byte[1444];
                int length;
                while ((byteread = inStream.read(buffer)) != -1) {
                    bytesum += byteread; //字节数 文件大小
                    System.out.println(bytesum);
                    fs.write(buffer, 0, byteread);
                }
                inStream.close();
            }
        } catch (Exception e) {
            System.out.println("复制单个文件操作出错");
            e.printStackTrace();

        }

    }

    /**
     * 复制整个文件夹内容
     *
     * @param oldPath String 原文件路径 如：c:/fqf
     * @param newPath String 复制后路径 如：f:/fqf/ff
     * @return boolean
     */
    public static ArrayList<String> copyFolder(String oldPath, String newPath) {
        ArrayList<String> fileList = new ArrayList();
        try {
            (new File(newPath)).mkdirs(); //如果文件夹不存在 则建立新文件夹
            File a = new File(oldPath);
            String[] file = a.list();
            File temp = null;
            for (int i = 0; i < file.length; i++) {
                if (oldPath.endsWith(File.separator)) {
                    temp = new File(oldPath + file[i]);
                } else {
                    temp = new File(oldPath + File.separator + file[i]);
                }

                if (temp.isFile() && temp.getName().endsWith("mp4")) {
                    FileInputStream input = new FileInputStream(temp);
                    String newFileName = newPath + "/" +
                            (temp.getName()).toString();
                    FileOutputStream output = new FileOutputStream(newFileName);
                    byte[] b = new byte[1024 * 5];
                    int len;
                    while ((len = input.read(b)) != -1) {
                        output.write(b, 0, len);
                    }
                    output.flush();
                    output.close();
                    input.close();
                    fileList.add(newFileName);
                }
                if (temp.isDirectory()) {//如果是子文件夹
                    copyFolder(oldPath + "/" + file[i], newPath + "/" + file[i]);
                }
            }
        } catch (Exception e) {
            System.out.println("复制整个文件夹内容操作出错");
            e.printStackTrace();
        } finally {
            return fileList;
        }

    }

    public static boolean videoFileExists(String path) {
        (new File(path)).mkdirs(); //如果文件夹不存在 则建立新文件夹
        File a = new File(path);
        String[] file = a.list();
        if (file != null) {
            for (int i = 0; i < file.length; i++) {
                if (file[i].toLowerCase().endsWith("mp4")) {
                    return true;
                }
            }
        }
        return false;
    }


    public static ArrayList<String> getLocalFileList(String path) {
        ArrayList<String> fileList = new ArrayList();
        try {
            (new File(path)).mkdirs(); //如果文件夹不存在 则建立新文件夹
            File a = new File(path);
            String[] file = a.list();
            File temp = null;
            for (int i = 0; i < file.length; i++) {
                if (path.endsWith(File.separator)) {
                    temp = new File(path + file[i]);
                } else {
                    temp = new File(path + File.separator + file[i]);
                }

                if (temp.isFile() && temp.getName().toLowerCase().endsWith("mp4")) {
                    fileList.add(temp.getAbsolutePath());
                }
            }
        } catch (Exception e) {
            System.out.println("获取文件夹内容操作出错");
            e.printStackTrace();
        } finally {
            return fileList;
        }

    }

    private static AutoResetEvent ase = new AutoResetEvent(true);

    public static boolean downloadFile(String src, String host, String localDest) throws InterruptedException, UnsupportedEncodingException {
        ase.waitOne(10 * 60 * 1000);
        final String url = host + src;
        final long startTime = System.currentTimeMillis();
        final boolean[] downloaded = {false};
        fileLogger.info("DOWNLOAD start to download media = " + src);
        try {
            Request request = new Request.Builder().url(url).build();
            new OkHttpClient().newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    fileLogger.info("DOWNLOAD onFailure download failed");
                    ase.set();
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    Sink sink;
                    BufferedSink bufferedSink = null;
                    try {
                        (new File(localDest)).mkdirs();
                        File dest = new File(localDest + "/" + extractMediaFile(src));
                        if (!dest.exists()) {
                            fileLogger.info("DOWNLOAD file does not exist, create new file");
                            sink = Okio.sink(dest);
                            bufferedSink = Okio.buffer(sink);
                            bufferedSink.writeAll(response.body().source());
                            bufferedSink.close();
                        } else {
                            fileLogger.info("DOWNLOAD file already exist, no need to download");
                        }

                        downloaded[0] = true;
                        fileLogger.info("DOWNLOAD totalTime = " + (System.currentTimeMillis() - startTime));
                    } catch (Exception e) {
                        e.printStackTrace();
                        fileLogger.info("DOWNLOAD exception download failed");
                    } finally {
                        if (bufferedSink != null) {
                            bufferedSink.close();
                        }
                        ase.set();
                    }
                }
            });
        } catch (Exception e) {
            ase.set();
            fileLogger.error(e.toString());
        }
        ase.waitOne(10 * 60 * 1000);
        ase.set();
        return downloaded[0];
    }

    public static String extractMediaFile(String url) {
        //var f = "api/media/view/0/WeChat Image_20181115164551.jpg?buId=2d41a66f-6b89-4af9-be8a-d076ad62bc0a";
        if (url != null && url.length() > 4) {
            String fileName = url.substring(url.lastIndexOf("/") + 1, url.lastIndexOf("?"));
            return fileName;
        }
        return null;
    }

    public static String encodeUtf8(String s) throws UnsupportedEncodingException {
        return URLEncoder.encode(s, "UTF-8");
    }

    public static String decodeUtf8(String s) throws UnsupportedEncodingException {
        return URLDecoder.decode(s, "UTF-8");
    }


//    public static void zip(String fileFullPath, String zipToFileFullPath) {
//        // Input and OutputStreams are defined outside of the try/catch block
//        // to use them in the finally block
//        ZipOutputStream outputStream = null;
//        InputStream inputStream = null;
//
//        try {
//            // Prepare the files to be added
//            ArrayList filesToAdd = new ArrayList();
//            filesToAdd.add(new File(fileFullPath));
////            filesToAdd.add(new File("c:\\ZipTest\\myvideo.avi"));
////            filesToAdd.add(new File("c:\\ZipTest\\mysong.mp3"));
//
//            //Initiate output stream with the path/file of the zip file
//            //Please note that ZipOutputStream will overwrite zip file if it already exists
//            outputStream = new ZipOutputStream(new FileOutputStream(new File(zipToFileFullPath)));
//
//            // Initiate Zip Parameters which define various properties such
//            // as compression method, etc. More parameters are explained in other
//            // examples
//
//            ZipParameters parameters = new ZipParameters();
//            //Deflate compression or store(no compression) can be set below
//            parameters.setCompressionMethod(Zip4jConstants.COMP_STORE);
//
//            // Set the compression level. This value has to be in between 0 to 9
//            // Several predefined compression levels are available
//            // DEFLATE_LEVEL_FASTEST - Lowest compression level but higher speed of compression
//            // DEFLATE_LEVEL_FAST - Low compression level but higher speed of compression
//            // DEFLATE_LEVEL_NORMAL - Optimal balance between compression level/speed
//            // DEFLATE_LEVEL_MAXIMUM - High compression level with a compromise of speed
//            // DEFLATE_LEVEL_ULTRA - Highest compression level but low speed
//            parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
//
//            //This flag defines if the files have to be encrypted.
//            //If this flag is set to false, setEncryptionMethod, as described below,
//            //will be ignored and the files won't be encrypted
//            parameters.setEncryptFiles(false);
//            //Zip4j supports AES or Standard Zip Encryption (also called ZipCrypto)
//            //If you choose to use Standard Zip Encryption, please have a look at example
//            //as some additional steps need to be done while using ZipOutputStreams with
//            //Standard Zip Encryption
//            //parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
//
//            //If AES encryption is used, this defines the key strength
//            //parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
//
//            //self descriptive
//            //parameters.setPassword("YourPassword");
//
//            //Now we loop through each file and read this file with an inputstream
//            //and write it to the ZipOutputStream.
//            for (int i = 0; i < filesToAdd.size(); i++) {
//                File file = (File) filesToAdd.get(i);
//
//                //This will initiate ZipOutputStream to include the file
//                //with the input parameters
//                outputStream.putNextEntry(file, parameters);
//
//                //If this file is a directory, then no further processing is required
//                //and we close the entry (Please note that we do not close the outputstream yet)
//                if (file.isDirectory()) {
//                    outputStream.closeEntry();
//                    continue;
//                }
//
//                //Initialize inputstream
//                inputStream = new FileInputStream(file);
//                byte[] readBuff = new byte[4096];
//                int readLen = -1;
//
//                //Read the file content and write it to the OutputStream
//                while ((readLen = inputStream.read(readBuff)) != -1) {
//                    outputStream.write(readBuff, 0, readLen);
//                }
//
//                //Once the content of the file is copied, this entry to the zip file
//                //needs to be closed. ZipOutputStream updates necessary header information
//                //for this file in this step
//                outputStream.closeEntry();
//
//                inputStream.close();
//            }
//
//            //ZipOutputStream now writes zip header information to the zip file
//            outputStream.finish();
//
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            if (outputStream != null) {
//                try {
//                    outputStream.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//
//            if (inputStream != null) {
//                try {
//                    inputStream.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//    }

    /**
     * @desc 只用来转换用
     * @info Created by LzPeng on 2020/4/16 9:34
     */
    public static String use(String v1) {
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal("0");
        return b1.add(b2).toString();
    }

}
