package com.zjty.inspect.utils;

import com.github.junrar.Archive;
import com.github.junrar.rarfile.FileHeader;
import lombok.extern.slf4j.Slf4j;
import net.lingala.zip4j.core.ZipFile;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.MappedByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;
import java.time.LocalDate;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Slf4j
public class FileUtil {

    static int BUFFER_SIZE = 1024;

    public static String createFilePath(){
        //"./"+name+"/"+split1[0]
        String[] split = UUIDUtil.getUUID().split("-");
        String time = LocalDate.now().toString();
        String filePath = time + "/"+split[0];
        return filePath;
    }

    public static int readFileNumber(File file){
        int linenumber = 0;
        try{
            if(file.exists()){
                FileReader fr = new FileReader(file);
                LineNumberReader lnr = new LineNumberReader(fr);

                while (lnr.readLine() != null){
                    linenumber++;
                }
                lnr.close();
                return linenumber;
            }else{
                return linenumber;
            }
        }catch(IOException e){
            log.error(e.getMessage());
        }
        return linenumber;
    }
    /**
     * 保存文件到本地
     * @param multipartFile
     * @return
     * @throws IOException
     */
    public static File saveToLocal(MultipartFile multipartFile) throws IOException {
        String name = LocalDate.now().toString();
        String[] split1 = UUIDUtil.getUUID().split("-");
        // 获取文件名
        String fileName = multipartFile.getOriginalFilename();
        // 获取文件后缀
        String prefix=fileName.substring(fileName.lastIndexOf("."));
        // 用uuid作为文件名，防止生成的临时文件重复
        final File excelFile = File.createTempFile(System.currentTimeMillis()+fileName, prefix);
        // MultipartFile to File
        multipartFile.transferTo(excelFile);
        if(".zip".equals(prefix)){
            FileUtil.unPackZip(excelFile,"", "./"+name+"/"+split1[0]);
        }else{
            FileUtil.unPackRar(excelFile, "./"+name+"/"+split1[0]);
        }
        String[] split = fileName.split("\\.");
        File file3 = new File("./"+name+"/"+split1[0]);
        excelFile.delete();
        log.info("end unpack file");
        return file3;
    }

    /**
     * zip文件解压
     *
     * @param destPath 解压文件路径
     * @param zipFile  压缩文件
     * @param password 解压密码(如果有)
     */
    public static void unPackZip(File zipFile, String password, String destPath) {
        try {
            ZipFile zip = new ZipFile(zipFile);
            /*zip4j默认用GBK编码去解压,这里设置编码为GBK的*/
            zip.setFileNameCharset("GBK");
            log.info("begin unpack zip file....");
            zip.extractAll(destPath);
            // 如果解压需要密码
            if (zip.isEncrypted()) {
                zip.setPassword(password);
            }
        } catch (Exception e) {
            log.error("unPack zip file to " + destPath + " fail ....", e.getMessage(), e);
        }
    }

    /**
     * rar文件解压(不支持有密码的压缩包)
     *
     * @param rarFile  rar压缩包
     * @param destPath 解压保存路径
     */
    public static void unPackRar(File rarFile, String destPath) {
        try (Archive archive = new Archive(rarFile)) {
            if (null != archive) {
                FileHeader fileHeader = archive.nextFileHeader();
                File file = null;
                while (null != fileHeader) {
                    // 防止文件名中文乱码问题的处理
                    String fileName = fileHeader.getFileNameW().isEmpty() ? fileHeader.getFileNameString() : fileHeader.getFileNameW();
                    if (fileHeader.isDirectory()) {
                        //是文件夹
                        file = new File(destPath + File.separator + fileName);
                        file.mkdirs();
                    } else {
                        //不是文件夹
                        file = new File(destPath + File.separator + fileName.trim());
                        if (!file.exists()) {
                            if (!file.getParentFile().exists()) {
                                // 相对路径可能多级，可能需要创建父目录.
                                file.getParentFile().mkdirs();
                            }
                            file.createNewFile();
                        }
                        FileOutputStream os = new FileOutputStream(file);
                        archive.extractFile(fileHeader, os);
                        os.close();
                    }
                    fileHeader = archive.nextFileHeader();
                }
            }
        } catch (Exception e) {
            log.error("unpack rar file fail....", e.getMessage(), e);
        }
    }
    /**
     * 将内容写人文件中
     * @param content 写入内容
     * @param path 文件路径（如：F:/a/b/test.txt）
     */
    public static void write(String content, String path) {
        // 检测文件夹是否存在，不存在则创建文件夹和文件
        createFile(path);
        FileWriter writer = null;
        try {
            writer = new FileWriter(path);
            writer.write(content);
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建文件
     * @param path 文件路径
     * @return 文件路径（如：F:/a/b/test.txt）
     */
    private static File createFile(String path) {
        // 创建文件夹
        if (path.contains("/")) {
            String[] split = path.split("/");
            String fileName = split[split.length-1];
            String dirPath = path.replace(fileName, "");
            File dir = new File(dirPath);
            if (!dir.exists()) {
                dir.mkdirs();
            }
        }
        File file = new File(path);
        if(file.exists()){
            file.delete();
        }
        if (!file.getParentFile().exists()) {
            boolean mkdir = file.getParentFile().mkdirs();
            if (!mkdir) {
                throw new RuntimeException("创建目标文件所在目录失败！");
            }
        }
        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }

    public static void main(String[] args) {
        String fileName = "master-sdsd-sdd-fff.zip";
        String prefix=fileName.substring(fileName.lastIndexOf("."));
        System.out.println(prefix);
        boolean equals = prefix.equals(".zip");
        System.out.println(equals);
    }
}
