package com.lunhan.xxx.common.util;

import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.charset.Charset;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

/**
 * 文件工具类
 * @author linliu
 * @date 2019-03-20
 */
public final class FileUtil {
    private FileUtil() {
        throw new IllegalStateException("Utility class");
    }

    static final String TITLE = "FileUtil";
    static final Integer EXCEL_SHEET_MAXROW = 65536;
    static final String STR_FAILD = "generate excel is faild!";
    static final String STR_UPLOADEXCEL = "list to excel and upload file service";
    static final String STR_DEFAULT_SHEETNAME = "Sheet1";

    /**
     * 根据文件contentType生成一个文件名
     * @param fileContentType contentType
     */
    public static String getNewFileNameByType(String fileContentType) {
        String timeStamp = Long.toString(System.currentTimeMillis());
        return timeStamp + FileUtil.getFileExtByType(fileContentType);
    }

    /**
     * 根据文件contentType生成一个文件名
     * @param fileContentType contentType
     */
    public static String getFileExtByType(String fileContentType) {
        String result = checkImage(fileContentType);
        if (StringUtil.isNotNullOrEmpty(result)) {
            return result;
        }

        result = checkRar(fileContentType);
        if (StringUtil.isNotNullOrEmpty(result)) {
            return result;
        }

        result = checkMedia(fileContentType);
        if (StringUtil.isNotNullOrEmpty(result)) {
            return result;
        }

        result = checkXml(fileContentType);
        if (StringUtil.isNotNullOrEmpty(result)) {
            return result;
        }

        result = checkOffice(fileContentType);
        if (StringUtil.isNotNullOrEmpty(result)) {
            return result;
        }
        return ".txt";
    }

    /**
     * 验证文件contentType是否是图片
     * @param fileContentType contentType
     */
    private static String checkImage(String fileContentType) {
        String result;
        switch (fileContentType) {
            case "image/jpeg":
            case "application/x-jpg":
                result = ".jpg";
                break;
            case "image/gif":
                result = ".gif";
                break;
            case "image/png":
                result = ".png";
                break;
            case "image/bmp":
                result = ".bmp";
                break;
            default:
                result = "";
                break;
        }
        return result;
    }

    /**
     * 验证文件contentType是否是压缩包
     * @param fileContentType contentType
     */
    private static String checkRar(String fileContentType) {
        String result;
        switch (fileContentType) {
            case "application/zip":
                result = ".zip";
                break;
            case "application/x-rar":
                result = ".rar";
                break;
            case "application/x-7z-compressed":
                result = ".7z";
                break;
            case "application/x-gzip":
                result = ".gz";
                break;
            default:
                result = "";
                break;
        }
        return result;
    }

    /**
     * 验证文件contentType是否是媒体文件
     * @param fileContentType contentType
     */
    private static String checkMedia(String fileContentType) {
        String result;
        switch (fileContentType) {
            case "video/mpeg":
                result = ".mp2";
                break;
            case "video/mp4":
                result = ".mp4";
                break;
            case "video/3gpp":
                result = ".3gp";
                break;
            case "video/x-flv":
                result = ".flv";
                break;

            case "audio/mpeg":
                result = ".mp3";
                break;
            case "audio/x-flac":
                result = ".flac";
                break;
            default:
                result = "";
                break;
        }
        return result;
    }

    /**
     * 验证文件contentType是否是xml
     * @param fileContentType contentType
     */
    private static String checkXml(String fileContentType) {
        String result;
        switch (fileContentType) {
            case "application/xml":
            case "text/html":
                result = ".xml";
                break;
            default:
                result = "";
                break;
        }
        return result;
    }

    /**
     * 验证文件contentType是否是office
     * @param fileContentType contentType
     */
    private static String checkOffice(String fileContentType) {
        String result;
        switch (fileContentType) {
            case "application/vnd.ms-excel":
                result = ".xls";
                break;
            case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
                result = ".xlsx";
                break;
            case "application/msword":
                result = ".doc";
                break;
            case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
                result = ".docx";
                break;
            case "application/vnd.ms-powerpoint":
                result = ".ppt";
                break;
            case "application/vnd.openxmlformats-officedocument.presentationml.presentation":
                result = ".pptx";
                break;
            default:
                result = "";
                break;
        }
        return result;
    }

    /**
     * 根据文件名识别文件 mediaType
     * @author linliu
     * @date 2019-06-26
     * @param fileName 文件名
     */
    public static String getMediaTypeByFileName(String fileName) {
        if (StringUtil.isNullOrEmpty(fileName)) {
            return "";
        }
        String[] arrayPath = StringUtil.split(fileName, "/");
        String realFileName = arrayPath[arrayPath.length - 1];
        String[] array = StringUtil.split(realFileName, "\\.");
        String fileSuffix = "." + array[array.length - 1];
        return getOfficeMediaTypeByFileName(fileSuffix);
    }

    /**
     * 根据文件拓展名识别 office文件
     * @param fileSuffix 拓展名
     */
    private static String getOfficeMediaTypeByFileName(String fileSuffix) {
        String result;
        switch (fileSuffix) {
            case ".xls":
                result = "application/vnd.ms-excel";
                break;
            case ".xlsx":
                result = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                break;
            case ".doc":
                result = "application/msword";
                break;
            case ".docx":
                result = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
                break;
            case ".ppt":
                result = "application/vnd.ms-powerpoint";
                break;
            case ".pptx":
                result = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
                break;
            default:
                result = getImageMediaTypeByFileName(fileSuffix);
                break;
        }
        return result;
    }

    /**
     * 根据文件拓展名识别 图片文件
     * @param fileSuffix 拓展名
     */
    private static String getImageMediaTypeByFileName(String fileSuffix) {
        String result;
        switch (fileSuffix) {
            case ".jpeg":
                result = "image/jpeg";
                break;
            case ".jpg":
                result = "application/x-jpg";
                break;
            case ".gif":
                result = "image/gif";
                break;
            case ".png":
                result = "image/png";
                break;
            case ".bmp":
                result = "image/bmp";
                break;
            default:
                result = getRarMediaTypeByFileName(fileSuffix);
                break;
        }
        return result;
    }

    /**
     * 根据文件拓展名识别 压缩文件
     * @param fileSuffix 拓展名
     */
    private static String getRarMediaTypeByFileName(String fileSuffix) {
        String result;
        switch (fileSuffix) {
            case ".zip":
                result = "application/zip";
                break;
            case ".rar":
                result = "application/x-rar";
                break;
            case ".7z":
                result = "application/x-7z-compressed";
                break;
            case ".gz":
                result = "application/x-gzip";
                break;
            default:
                result = getOtherMediaTypeByFileName(fileSuffix);
                break;
        }
        return result;
    }

    /**
     * 根据文件拓展名识别 其他文件
     * @param fileSuffix 拓展名
     */
    private static String getOtherMediaTypeByFileName(String fileSuffix) {
        String result;
        switch (fileSuffix) {
            case ".pdf":
                result = "application/pdf";
                break;
            case ".txt":
                result = "text/plain";
                break;
            default:
                result = "";
                break;
        }
        return result;
    }

    /**
     * 读取本地文件内容
     * @param filePath 文件路径
     */
    public static String readFileContent(String filePath) {
        return readFileContent(filePath, null);
    }

    /**
     * 读取本地文件内容
     * @param filePath 文件路径
     * @param charset 编码格式
     */
    public static String readFileContent(String filePath, Charset charset) {
        if(null==charset) {
            charset = Charset.forName("utf-8");
        }
        File file = new File(filePath.replaceAll("\\\\", "/"));
        StringBuilder localStrBulider = new StringBuilder();
        if(file.isFile() && file.exists()) {
            String lineStr;
            try (InputStreamReader inputStreamReader=new InputStreamReader(new FileInputStream(file), charset)){
                BufferedReader bufferReader = new BufferedReader(inputStreamReader);
                while((lineStr = bufferReader.readLine()) != null) {
                    localStrBulider.append(lineStr);
                }
                bufferReader.close();
            } catch (IOException e) {
                //TODO log
            }
        } else {
            //TODO log
            return null;
        }
        return localStrBulider.toString();
    }

    /**
     * 读取本地文件内容
     * @param filePath 文件路径
     */
    public static byte[] readFile(String filePath) throws IOException {
        File f = new File(filePath);
        if (!f.exists()) {
            throw new FileNotFoundException(filePath);
        }

        ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length());
        BufferedInputStream in = null;
        try {
            in = new BufferedInputStream(new FileInputStream(f));
            int bufSize = 1024;
            byte[] buffer = new byte[bufSize];
            int len;
            while (-1 != (len = in.read(buffer, 0, bufSize))) {
                bos.write(buffer, 0, len);
            }
            return bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            bos.close();
        }
    }

    /**
     * 文件上传
     * @return
     */
    public static String uploadUtil(MultipartFile myFile, String fileUrlName) {
        String urlName="";
        try {
            DateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");
            //文件名称
            String name = df.format(new Date());

            Random r = new Random();
            for (int i = 0; i < 3; i++) {
                name += r.nextInt(10);
            }
            int idx = myFile.getOriginalFilename().lastIndexOf(".");
            String ext = myFile.getOriginalFilename().substring(idx);
            //保存文件       File位置 (全路径)   /upload/fileName

            String url = "/" + fileUrlName+"/" ;
            //相对路径
            String path = name + "." + ext;
            File file = new File(url);
            if (!file.exists()) {
                file.mkdirs();
            }
            myFile.transferTo(new File(url + path));
            urlName=path;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return urlName;
    }

    /**
     * 删除文件
     * @param path
     */
    public static void deleteFile(String path){
        File file=new File(path);
        if(file.exists()){
            file.delete();
        }
    }
}