package com.bohuikeji.frame.module.admin.utils;

import com.bohuikeji.frame.module.admin.exception.WebVerifiedException;
import jodd.http.HttpRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.time.LocalDate;
import java.util.Random;

/**
 * 本地文件上传工具类
 * 【注意】该工具类为本地文件上传下载工具类，集群、分布式、虚拟机环境下慎用
 * @author 10552
 *
 */
@Slf4j
public class FileUtil {

	/**
	 *    上传单个临时文件
	 *    注意：临时文件存放位置由系统环境决定，可能会被删除一般用于保存缓存文件
	 * @param muFile 文件对象
	 * @return 返回文件磁盘访问路径
	 * 【警告】该方法已废弃，上传文件请使用对象存储类工具类：MinioUtil
	 */
	@Deprecated
	public static String uploadTmpFile(MultipartFile muFile) {
		File tmpDir = FileUtils.getTempDirectory();
		System.out.println("得到系统临时文件路径：" + tmpDir.getAbsolutePath());
		String tmpFileName = (Math.random() * 10000 + "").replace(".", "") + "_" + muFile.getOriginalFilename();
		try {
			muFile.transferTo(new File(tmpDir, tmpFileName));
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return tmpFileName;
	}
	/**
	 *    上传多个临时文件
	 *    注意：临时文件存放位置由系统环境决定，可能会被删除一般用于保存缓存文件
	 * @param muFiles 文件对象
	 * @return 返回多个文件磁盘访问路径以分号分割
	 * 【警告】该方法已废弃，上传文件请使用对象存储类工具类：MinioUtil
	 */
	@Deprecated
	public static String uploadTmpFiles(MultipartFile[] muFiles) {
		File tmpDir = FileUtils.getTempDirectory();
		System.out.println("得到系统临时文件路径：" + tmpDir.getAbsolutePath());
		StringBuilder fileNames=new StringBuilder();
		for(int i=0;i<muFiles.length;i++) {
			String tmpFileName = (Math.random() * 10000 + "").replace(".", "") + "_" + muFiles[i].getOriginalFilename();
			try {
				muFiles[i].transferTo(new File(tmpDir, tmpFileName));
				fileNames.append(tmpFileName);
				fileNames.append(";");
			} catch (IllegalStateException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return fileNames.deleteCharAt(fileNames.length()-1).toString();
	}
	/**
	 *    上传单个文件
	 *    注意：此方法返回文件的相对访问url
	 * @param muFile 文件对象
	 * @return 返回文件的相对url
	 *
	 * 【警告】该方法已废弃，上传文件请使用对象存储类工具类：MinioUtil
	 */
	@Deprecated
	public static String uploadFile(MultipartFile muFile) {
		String FileName = getFilePathName(muFile,true);
		String filePathName=System.getProperty("user.dir").replaceAll("\\\\", "/")+FileName;
		try {
			File file = new File(filePathName);
			File fileParent = file.getParentFile();
			if(!fileParent.exists()){
			    fileParent.mkdirs();
			}
			muFile.transferTo(file);
			System.out.println("文件存放路径：" + filePathName);
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return FileName;
	}
	/**
	 *    上传多个个文件
	 *    注意：此方法返回文件的相对访问url
	 * @param muFiles 文件对象组
	 * @return 返回文件的相对url组，以分号分割
	 *
	 * 【警告】该方法已废弃，上传文件请使用对象存储类工具类：MinioUtil
	 */
	@Deprecated
	public static String uploadFiles(MultipartFile[] muFiles) {
		StringBuilder fileUrls=new StringBuilder();
		String fileDir=System.getProperty("user.dir").replaceAll("\\\\", "/");
		for(int i=0;i<muFiles.length;i++) {
			String FileName = getFilePathName(muFiles[i],false);
			String filePathName=fileDir+FileName;
			try {
				File file = new File(filePathName);
				File fileParent = file.getParentFile();
				if(!fileParent.exists()){
				    fileParent.mkdirs();
				}
				muFiles[i].transferTo(file);
				System.out.println("文件存放路径：" + filePathName);
				fileUrls.append(FileName);
				fileUrls.append(";");
			} catch (IllegalStateException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return fileUrls.deleteCharAt(fileUrls.length()-1).toString();
	}
	/**
     * 	 获取文件名
     * @param muFile 文件
     * @param isRetain 是否保留源文件名
     * @return 返回文件名，以当前年月日作为前缀路径
     */
    public static String getFilePathName(MultipartFile muFile,boolean isRetain){
        String fileName = muFile.getOriginalFilename();
        String name=fileName;
        String prefix="";
        if(fileName.indexOf('.')!=-1) {
        	name=fileName.substring(0,fileName.indexOf('.'));
            prefix=fileName.substring(fileName.lastIndexOf("."));
        }

        LocalDate date = LocalDate.now();
        StringBuilder filePathName=new StringBuilder("/upload/");
        filePathName.append(date.getYear());
        filePathName.append("/");
        filePathName.append(date.getMonthValue());
        filePathName.append("/");
        filePathName.append(date.getDayOfMonth());
        filePathName.append("/");
        Random r = new Random();
        int pix=r.ints(1, (100 + 1)).findFirst().getAsInt();
        //filePathName.append(System.currentTimeMillis());
        //filePathName.append(""+pix);
        //文件名超过64字符则截取
        if(isRetain){
           /* filePathName.append("_");
            if(name.length()>64){
                name=name.substring(0,64);
            }*/
            filePathName.append(name);
        }
        filePathName.append(prefix);
        return filePathName.toString();
    }


	/**
	 * 获取工作路径
	 * @return
	 */
    public static String getUserDir(){
		return System.getProperty("user.dir").replaceAll("\\\\", "/");
	}

	/**
	 * 获取系统临时文件夹
	 * @return
	 */
	public static String getTempDir(){
		String tmpPath=FileUtils.getTempDirectory().getAbsolutePath();
		log.info("获取系统临时文件夹：[{}]",tmpPath);
    	return tmpPath;
	}

	public static String getDateDir(){
		LocalDate date = LocalDate.now();
    	StringBuilder str=new StringBuilder(8);
		str.append(date.getYear());
		str.append(date.getMonthValue());
		str.append(date.getDayOfMonth());
		return str.toString();
	}

	/**
	 * 通用网络文件下载文件
	 * @param url http或则https开头的网络文件地址
	 * @return
	 */
	public static InputStream download(String url){
		return new ByteArrayInputStream(HttpRequest.get(url).send().bodyBytes());
	}

	/**
	 * 判断文件大小
	 *
	 * @param len
	 *            文件长度
	 * @param size
	 *            限制大小
	 * @param unit
	 *            限制单位（B,K,M,G）
	 * @return
	 */
	public static boolean checkFileSize(Long len, int size, String unit) {
//        long len = file.length();
		double fileSize = 0;
		if ("B".equals(unit.toUpperCase())) {
			fileSize = (double) len;
		} else if ("K".equals(unit.toUpperCase())) {
			fileSize = (double) len / 1024;
		} else if ("M".equals(unit.toUpperCase())) {
			fileSize = (double) len / 1048576;
		} else if ("G".equals(unit.toUpperCase())) {
			fileSize = (double) len / 1073741824;
		}
		if (fileSize > size) {
			return false;
		}
		return true;
	}

	/**
	 * 读取资源目录下的文件
	 * @return
	 * @throws IOException
	 */
	public static InputStream readResourceFile(String fileName){
		Resource resource = new ClassPathResource(fileName);
		try {
			return  resource.getInputStream();
		} catch (IOException e) {
			log.error("读取资源目录文件失败，文件名：[{}]",fileName,e);
			throw new WebVerifiedException("读取资源目录文件失败");
		}
	}
	/**
	 * 获取文件名
	 *
	 * @param
	 * @return
	 */
	public static String getPathName() {
		LocalDate date = LocalDate.now();
		StringBuilder filePathName = new StringBuilder();
		filePathName.append(date.getYear());
		filePathName.append("/");
		filePathName.append(date.getMonthValue());
		filePathName.append("/");
		filePathName.append(date.getDayOfMonth());
		filePathName.append("/");
		int pix = new Random().ints(1, (100 + 1)).findFirst().getAsInt();
		filePathName.append(System.currentTimeMillis());
		filePathName.append("" + pix);
		return filePathName.toString();
	}

	/**
	 * 根据mFile创建File文件
	 * @param mFile
	 * @return
	 */
	public static File createTmpFile(MultipartFile mFile){
		// 获取文件名
		String fileName = mFile.getOriginalFilename();
		// 获取文件后缀
		String prefix = fileName.substring(fileName.lastIndexOf("."));
		// 若需要防止生成的临时文件重复,可以在文件名后添加随机码
		try {
			File file = File.createTempFile(fileName, prefix);
			mFile.transferTo(file);
			return file;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}
