package com.koobietech.eas.common.utils;

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.stereotype.Component;

import java.io.*;
import java.nio.channels.FileChannel;
import java.nio.file.*;
import java.text.DecimalFormat;

@Component
public class FileManager {

    String separator = File.separator ;

    /**********************************
     * 文件夹 操作 工具类
     ***********************************/

    /**
     * 获取文件夹大小
     */
    public Double getFolderSize(String sizePath) {
        Double size = 0.0;
        Path folderPath = Paths.get(sizePath);
        DirectoryStream<Path> stream = null;
        try {
            stream = Files.newDirectoryStream(folderPath);
            for (Path path : stream) {
                if (Files.isRegularFile(path)) {
                    size += Files.size(path);
                } else if (Files.isDirectory(path)) {
                    size += getFolderSize(path.toFile().getAbsolutePath());
                }
            }
        } catch (IOException e) {}finally {
            try {
                stream.close();
            } catch (IOException e) {}
        }
        if ( size > 0  ) {
            size = size / 1024 / 1024 ;
            DecimalFormat df = new DecimalFormat("#.####");
            String result = df.format(size);
            return Double.valueOf(result);
        } else {
            return  0.0;
        }
    }

    /**
     * 移动文件夹
     * @param oldPath 源文件夹路径
     * @param newPath 目标文件夹路径
     */
    public boolean moveFolder(String oldPath, String newPath) {
        File sourceFolder = new File(oldPath);
        //把源文件转移到目标文件夹下
        File targetFolder = new File(newPath, sourceFolder.getName());
        if (!sourceFolder.exists() || sourceFolder.isFile()) {
            return false;
        }
        if (sourceFolder.isDirectory()) {
            if (!targetFolder.exists()) {
                targetFolder.mkdir();
            }
            File[] files = sourceFolder.listFiles();
            if (files != null) {
                for (File file : files) {
                    if ( file.isFile() ) {
                        FileChannel sourceChannel = null;
                        FileChannel destChannel = null;
                        try {
                            sourceChannel = new FileInputStream(file).getChannel();
                            destChannel = new FileOutputStream(new File(targetFolder.getPath(), file.getName())).getChannel();
                            destChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
                            sourceChannel.close();
                            file.delete();
                        } catch (IOException e) {}finally {
                            try {
                                sourceChannel.close();
                                destChannel.close();
                            } catch (IOException e) {}
                        }
                    } else {
                        moveFolder(file.getPath(), new File(targetFolder.getPath(), file.getName()).getPath());
                    }
                }
            }
            sourceFolder.delete();
        }
        return true;
    }

    /**
     * 复制文件夹
     * @param oldPath
     * @param newPath
     * @return
     */
    public boolean copyFolder(String oldPath, String newPath, Boolean replaceFile) {
        File sourceFolder = new File(oldPath);
        File destFolder = new File(newPath);
        if (sourceFolder.isFile()) {
            return false;
        }
        if (!sourceFolder.exists()) {
            return false;
        }
        if (!destFolder.exists()) {
            destFolder.mkdir();
        }
        File[] files = sourceFolder.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isFile()) {
                    copyFile(file.getPath(), new File(newPath, file.getName()).getPath(), replaceFile);
                } else if (file.isDirectory()) {
                    copyFolder(file.getPath(), new File(newPath + separator + file.getName()).getPath(), replaceFile);
                }
            }
        }
        return true;
    }

    /**
     * 创建文件夹
     * @param path
     * @return
     */
    public boolean createPath(String path){
        File file = new File(path);
        if (!file.exists()){
            file.mkdirs();
        }
        return true;
    }

    /**
     * 判断文件夹是否存在
     * @param folderPath
     * @return
     */
    public boolean isFolderExists(String folderPath){
        return isFileExists(folderPath);
    }

    /**
     * 删除文件夹
     * @param folderPath
     * @return
     */
    public boolean deleteFolder(String folderPath){
        File fileFolder = new File(folderPath);
        if ( fileFolder != null && fileFolder.exists() ){
            if ( fileFolder.isDirectory() ){
                File[] files = fileFolder.listFiles();
                for (File file : files) {
                    if ( file.isDirectory() ){
                        deleteFolder(file.getAbsolutePath());
                    } else {
                        file.delete();
                    }
                }
            }
            fileFolder.delete();
        } else {
            return false;
        }
        return true;
    }


    /**********************************
     * Document 操作 工具类
     ***********************************/

    /**
     * 保存 Document 文档
     * @param document
     * @param savePath
     * @return
     */
    public boolean saveDocument(XWPFDocument document, String savePath){
        boolean ret = true;
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(savePath);
            document.write(fileOutputStream);
        } catch (IOException e) {
            ret = false;
        } finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {}
        }
        return ret;
    }

    /**
     * 保存 Document 文档
     * @param document
     * @param savePath
     * @param fileName
     * @return
     */
    public boolean saveDocument(XWPFDocument document, String savePath, String fileName){
        return saveDocument(document, savePath + fileName);
    }

    /**********************************
     * 文件 操作 工具类
     ***********************************/

    /**
     * 判断文件是否可读
     * @param filePath
     * @return
     */
    public boolean isFileCanRead(String filePath){
        File file = new File(filePath);
        return file.canRead();
    }

    /**
     * 判断文件是否可写
     * @param filePath
     * @return
     */
    public boolean isFileCanWrite(String filePath){
        File file = new File(filePath);
        return file.canWrite();
    }

    /**
     * 判断文件是否存在
     * @param filePath
     * @return
     */
    public boolean isFileExists(String filePath){
        File file = new File(filePath);
        return file.exists();
    }

    /**
     * 保存 文件
     * @param stream
     * @param savePath
     * @param fileName
     * @return
     */
    public boolean saveFile(InputStream  stream, String savePath, String fileName) {
        return saveFile(stream, savePath + fileName);
    }

    /**
     * 保存 文件
     * @param stream
     * @param savePath
     * @return
     */
    public boolean saveFile(InputStream stream, String savePath){
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(savePath);
            int bytesRead;
            byte[] buffer = new byte[1024];
            while ((bytesRead = stream.read(buffer)) != -1){
                fileOutputStream.write(bytesRead);
            }
        } catch (IOException e) {
            return  false;
        } finally {
            try {
                fileOutputStream.close();
            }catch (IOException e){}
        }
        return true;
    }

    /**
     * 删除文件
     * @param filePath
     * @return
     */
    public boolean deleteFile(String filePath){
        File file = new File(filePath);
        return file.delete();
    }

    /**
     * 复制文件
     * @param srcFile 源文件路径
     * @param destFile 目标文件路径
     * @return
     */
    public boolean copyFile(String srcFile, String destFile, Boolean replaceFile){
        Path srcFilePath = Paths.get(srcFile);
        Path destFilePath = Paths.get(destFile);
        try {
            if (replaceFile) {
                Files.copy(srcFilePath, destFilePath, StandardCopyOption.REPLACE_EXISTING);
            } else {
                Files.copy(srcFilePath, destFilePath, StandardCopyOption.COPY_ATTRIBUTES);
            }
        } catch (IOException e) {
            return false;
        }
        return true;
    }

    /**
     * 移动文件
     * @param srcFilePath 源文件路径
     * @param destFilePath 目标文件路径
     * @return
     */
    public boolean moveFile(String srcFilePath, String destFilePath, Boolean replaceFile){
        Path srcFile = Paths.get(srcFilePath);
        Path destFile = Paths.get(destFilePath);
        try {
            if (replaceFile) {
                Files.move(srcFile, destFile, StandardCopyOption.REPLACE_EXISTING);
            } else {
                Files.move(srcFile, destFile, StandardCopyOption.REPLACE_EXISTING);
            }
        } catch (IOException e) {
            return false;
        }
        return true;
    }

    /**
     * 获取文件大小
     * @param filePath 文件路径
     * @return
     */
    public Double getFileSize(String filePath) {
        Double size = 0.0;
        Path folderPath = Paths.get(filePath);
        if (Files.isRegularFile(folderPath)) {
            try {
                size += Files.size(folderPath);
            } catch (IOException e) {}
        }
        if ( size > 0.0  ) {
            size = size / 1024 / 1024 ;
            DecimalFormat df = new DecimalFormat("#.####");
            String result = df.format(size);
            return Double.valueOf(result);
        } else {
            return  0.0;
        }
    }

    /**
     * 获取文件流  注意关闭文件流
     * @param filePath
     * @return
     */
    public FileInputStream getArchiveFile(String filePath) {
        FileInputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileInputStream(filePath);
        } catch (FileNotFoundException e) {}
        return fileOutputStream;
    }
}
