package com.philisense.www.utils;

import cn.hutool.core.date.DateUtil;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.UUID;

/**
 * @description: 云存储工具类
 * @create: 2019-01-25 15:37
 **/
public class StorageUtils {

    /**
     * 生成文件名 包含路径 防止重复
     *
     * @param prefix 前缀
     * @param suffix 后缀
     * @return
     */
    public static String generateFileName(String prefix, String suffix) {
        //生成uuid
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        //文件路径
        String path = DateUtil.format(new Date(), "yyyyMMdd") + "/" + uuid;
        if (StringUtils.isNotBlank(prefix)) {
            path = prefix + '/' + path;
        }
        return path + suffix;
    }

    /**
     * 获取文件名后缀 包含.
     *
     * @param fileName 文件
     * @return
     */
    public static String getFileSuffixNamePoint(String fileName) {
        String suffix = fileName.substring(fileName.lastIndexOf("."));
        return suffix;
    }


    /**
     * 获取文件大小
     *
     * @param size
     * @return
     */
    public static String readableFileSize(long size) {
        if (size <= 0) {
            return "0";
        }
        final String[] units = new String[]{"B", "KB", "MB", "GB", "TB"};
        int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
        return new DecimalFormat("#,##0.#").format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups];
    }

    /**
     * 获取文件名后缀 不包含.
     *
     * @param fileName 文件
     * @return
     */
    public static String getFileSuffixName(String fileName) {
        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
        return suffix;
    }

    /**
     * 从路径中获取文件名
     *
     * @param path
     * @return
     */
    public static String getFileName(String path) {
        return path.substring(path.lastIndexOf("/") + 1);
    }

    /**
     * java获取文件的md5值
     * @param fis 输入流
     * @return
     */
    public static String md5HashCode(InputStream fis) {
        try {
            //拿到一个MD5转换器,如果想使用SHA-1或SHA-256，则传入SHA-1,SHA-256
            MessageDigest md = MessageDigest.getInstance("MD5");

            //分多次将一个文件读入，对于大型文件而言，比较推荐这种方式，占用内存比较少。
            byte[] buffer = new byte[1024];
            int length = -1;
            while ((length = fis.read(buffer, 0, 1024)) != -1) {
                md.update(buffer, 0, length);
            }
            fis.close();
            //转换并返回包含16个元素字节数组,返回数值范围为-128到127
            byte[] md5Bytes  = md.digest();
            BigInteger bigInt = new BigInteger(1, md5Bytes);//1代表绝对值
            return bigInt.toString(16);//转换为16进制
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 需要注意的是当删除某一目录时，必须保证该目录下没有其他文件才能正确删除，否则将删除失败。
     *
     * @param folder
     * @throws Exception
     */
    public static void deleteFolder(File folder) throws Exception {
        if (!folder.exists()) {
            throw new Exception("文件不存在");
        }

        File[] files = folder.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    // 递归直到目录下没有文件
                    deleteFolder(file);
                } else {
                    // 删除
                    file.delete();
                }
            }
        }
        // 删除
        folder.delete();

    }

    /**
     * 递归删除空文件夹
     * @param dir
     */
    public static void clear(File dir) {
        File[] dirs = dir.listFiles();
        for( int i = 0; i < dirs.length; i++ ) {
            if( dirs[i].isDirectory() ) {
                clear(dirs[i]);
            }
        }
        if(dir.isDirectory()) {
             dir.delete();
        }
    }

}
