package com.cpp.web.utils;


import cn.hutool.core.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.util.ResourceUtils;

import java.io.*;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFileAttributes;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 操作文件工具类
 *
 * @author tl
 * @date 2022-05-11 10:08:21
 */
@Slf4j
public class ParsingFileUtil {
    /*按⾏读取txt⽂件并返回⼀个List<String>集合
     *@param path
     *@return List<String>
     */
    public static List<String> getFileContent(File file) throws Exception {
        String encodingType = ParsingEfileUtil.getCharset(file);
        List<String> strList = new ArrayList();

        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(file);
            //将字节流向字符流转换
            inputStreamReader = new InputStreamReader(fileInputStream, encodingType);
            //创建字符流缓冲区
            bufferedReader = new BufferedReader(inputStreamReader);
            String line;
            //按⾏读取
            while ((line = bufferedReader.readLine()) != null) {
                strList.add(line);
            }


        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inputStreamReader != null) {
                try {
                    inputStreamReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return strList;
        }
    }


    public static String getParsingPath() {
        return createParsingDir("parsing");
    }

//    public static String getSendJyDataPath() {
//        return createParsingDir("ftp");
//    }

    private static String createParsingDir(String dir) {
        String path = "/home/syjy/ipp/" + dir;
        return path;
    }


    //把一个文件中的内容读取成一个String字符串
    public static String getStr(File jsonFile){
        String jsonStr = "";
        try {
            FileReader fileReader = new FileReader(jsonFile);
            Reader reader = new InputStreamReader(new FileInputStream(jsonFile),"utf-8");
            int ch = 0;
            StringBuffer sb = new StringBuffer();
            while ((ch = reader.read()) != -1) {
                sb.append((char) ch);
            }
            fileReader.close();
            reader.close();
            jsonStr = sb.toString();
            return jsonStr;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 移动本地文件
     *
     * @param remoteAbsoluteFile 远程文件名(包括完整路径)
     * @param localAbsoluteFile  本地文件名(包括完整路径)
     * @return 成功时，返回true，失败返回false
     * @throws Exception
     */
    public static void move(String localAbsoluteFile, String remoteAbsoluteFile) throws Exception {
//    File srcFile = new File(localAbsoluteFile);
//    File destDir = new File(remoteAbsoluteFile);
//    try {
//      if (!destDir.exists()) {// 如果目录不存在则创建目录
//        boolean b = destDir.mkdirs();
//        if (!b) // 如果创建失败则抛出异常
//          throw new RuntimeException(destDir + " 目录创建失败");
//      }
//      FileUtils.moveFile(srcFile, new File(remoteAbsoluteFile + File.separator + srcFile.getName()));
//    } catch (IOException e) {
//      throw new Exception("文件：" + srcFile.getName() + "移动到" + destDir.getPath() + "失败。", e);
//    }
        move(localAbsoluteFile, remoteAbsoluteFile, true);
    }

    public static void move(String localAbsoluteFile, String remoteAbsoluteFile, boolean overwrite) throws Exception {
        File srcFile = new File(localAbsoluteFile);
        File destDir = new File(remoteAbsoluteFile);
        StringBuilder opts = new StringBuilder();
        try {
            if (!destDir.exists()) {// 如果目录不存在则创建目录
                boolean b = destDir.mkdirs();
                if (!b) // 如果创建失败则抛出异常
                    throw new RuntimeException(destDir + " 目录创建失败");
            }
            File desFile = new File(remoteAbsoluteFile + File.separator + srcFile.getName());
            if (overwrite && desFile.exists()) {
                FileUtils.deleteQuietly(desFile);
                opts.append(" >> 覆盖 >> ");
            } else {
                opts.append(" >> 移动 >> ");
            }
            FileUtils.moveFile(srcFile, desFile);
            log.info("文件：" + srcFile.getName() + opts + destDir.getPath());
        } catch (IOException e) {
            throw new Exception("文件：" + srcFile.getName() + opts + destDir.getPath() + "失败。", e);
        }
    }

    public static void copy(String src, String des, boolean overwrite) throws Exception {
        File srcFile = new File(src);
        File desFile = new File(des);
        copy(srcFile, desFile, overwrite);
    }

    public static void copy(File srcFile, File desFile, boolean overwrite) throws Exception {
        if (overwrite && desFile.exists()) {
            FileUtils.deleteQuietly(desFile);
        }
        FileUtils.copyFile(srcFile, desFile);
    }

    public static InputStream toInputStream(File file, Charset source, Charset target) {
        InputStream inputStream = null;
        try {
            if (file.exists() && file.canRead()) {
                String context = FileUtils.readFileToString(file, source);
                inputStream = null == context ? null : IOUtils.toInputStream(context, target);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return inputStream;
    }

    public static File convert(File file, Charset source, Charset target) {
        if (file.exists() && file.canRead() && file.canWrite()) {
            return CharsetUtil.convert(file, source, target);
        }
        return null;
    }

    //文件内容md5加密
    public static String getMD5(byte[] fileByte) {
        String md5 = new String();
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(fileByte);
            byte b[] = md.digest();

            int i;

            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }

            md5 = buf.toString();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return md5;
    }

    /**
     * 获取文件创建时间
     *
     * @param fullFileName
     * @return
     */
    public static Long getFileCreateTime(String fullFileName) {
        Path path = Paths.get(fullFileName);
        BasicFileAttributeView basicview = Files.getFileAttributeView(path, BasicFileAttributeView.class, LinkOption.NOFOLLOW_LINKS);
        BasicFileAttributes attr;
        try {
            attr = basicview.readAttributes();
            Date createDate = new Date(attr.creationTime().toMillis());
            return createDate.getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new Date().getTime();
    }

    /**
     * 获取项目根路径
     *
     * @return
     */
    public static String getResourceBasePath() {
        // 获取跟目录
        File path = null;
        try {
            path = new File(ResourceUtils.getURL("classpath:").getPath());

        } catch (FileNotFoundException e) {
            // nothing to do
        }
        if (path == null || !path.exists()) {
            path = new File("");
        }

        String pathStr = path.getAbsolutePath();
        try {
            pathStr = URLDecoder.decode(pathStr, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        // 如果是在eclipse中运行，则和target同级目录,如果是jar部署到服务器，则默认和jar包同级
//    pathStr = pathStr.replace("\\target\\classes", "");

        return pathStr;
    }

    /**
     * 获取上报文件目录相对路径
     *
     * @return
     */
    public static String getFileUploadPath() {
        return createUploadAllDir("uploadFile");
    }

    /**
     * 获取下载文件目录相对路径
     *
     * @return
     */
    public static String getDownloadFilePath() {
        return createUploadAllDir("downloadFile");
    }

    /**
     * 获取下载文件目录相对路径
     *
     * @return
     */
    public static String getZxglFilePath() {
        return createUploadAllDir("zxgl");
    }

    /**
     * 获取日志目录相对路径
     *
     * @return
     */
    public static String getLogsPath() {
        return createUploadAllDir("logs");
    }

    /**
     * 获取系统脚本相对路径
     *
     * @return
     */
    public static String getBinPath() {
        return createUploadAllDir("bin");
    }

    /**
     * 程序备份相对路径
     *
     * @return
     */
    public static String getOriginalPath() {
        return createUploadAllDir("original");
    }

    /**
     * 系统资料相对路径
     *
     * @return
     */
    public static String getSystemFilePath() {
        return createUploadAllDir("systemFile");
    }

    /**
     * 获取被删除文件目录
     *
     * @return 路径
     */
    public static String getDeleteFilePath() {
        return createUploadAllDir("deleteFile");
    }

    /**
     * 程序运行相对路径
     *
     * @return
     */
    public static String getProducePath() {
        return createUploadAllDir("produce");
    }


    /**
     * 配置信息路径
     * @return
     */
    public static String getSettingsPath() {
        return createUploadAllDir("settings");
    }

    /**
     * 内网接收路径
     * @return
     */
    public static String getReceivePath() {
        return createUploadAllDir("receive");
    }

    /**
     * 报表相对路径
     *
     * @return
     */
    public static String getreportFormPath() {
        return createUploadAllDir("reportForm");
    }

    /**
     * 获取临时文件目录相对路径
     *
     * @return
     */
    public static String getTempFilePath() {
        return createUploadAllDir("tempFile");
    }

    public static String getSftpDownload() {
        return createUploadAllDir("sftpDownload");
    }


    public static String getOutDownload() {
        return createUploadAllDir("outDownload");
    }


    private static String createUploadAllDir(String dir) {
        String path = "";
        if (System.getProperties().getProperty("file.separator").equals("\\")) {
            path = new File(getResourceBasePath()).getParentFile().getParentFile().getParentFile().getAbsolutePath() + File.separator + dir;
            try {
                path = URLDecoder.decode(path, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            File file = new File(path);
            if (!file.exists()) {
                boolean b = file.mkdirs();
                if (!b)
                    log.error("目录创建失败" + path);
            }
        } else {
            path = "/home/syjy/cpp/" + dir;
        }
        return path;
    }

    /**
     * 获取环境数据导出文件目录相对路径
     *
     * @return
     */
    public static String getEnvironmentalDataFile() {
        return createUploadAllDir("environmentalDataFile");
    }


    /**
     * 设置用户和用户组
     *
     * @param filePath 文件路径
     * @param owner    用户
     * @param group    用户组
     */
    public static void setFileOwnerAndGroup(String filePath, String owner, String group) {
        Path path = FileSystems.getDefault().getPath(filePath);

        try {
            // 创建文件（如果不存在）
            if (!Files.exists(path)) {
                Files.createFile(path);
            }

            // 获取文件属性视图
            PosixFileAttributeView attributeView = Files.getFileAttributeView(
                    path, PosixFileAttributeView.class);

            // 获取当前的文件属性
            PosixFileAttributes attributes = attributeView.readAttributes();

            // 设置文件所有者和用户组
            attributeView.setOwner(FileSystems.getDefault().getUserPrincipalLookupService().lookupPrincipalByName(owner));
            attributeView.setGroup(FileSystems.getDefault().getUserPrincipalLookupService().lookupPrincipalByGroupName(group));

            log.info("{}文件所有者设置为: {},用户组设置为：{}" + filePath, attributeView.getOwner(), attributes.group());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    public static File checkGetPath(String path){
        File file = new File(path);
        if (!file.exists()){
            file.mkdirs();
        }

        return file;
    }



}
