package cn.util.file;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import cn.util.string.JsonKit;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
import cn.constant.CharsetKit;
import cn.util.core.IsKit;
import cn.util.core.LogKit;


public class FileKit  
{

	private static ClassPathResource resource;
	private static BufferedReader reader;
	private static String content;

	//获取目录下所有文件名的详细信息
	public static List<Map<String,Object>> getFilesInfo(String fielPath) {
		List<Map<String,Object>> fileList = new ArrayList<>();
		File file = new File(fielPath);
		if (!file.exists()) {
			return fileList;
		}
		File fa[] = file.listFiles();
		for (File fs : fa) {
			if (fs.isDirectory()) {
			}
			else {
				Map<String,Object> temp = new HashMap<>();
				temp.put("fileName",fs.getName());
				temp.put("filePath",fs.getPath());
				temp.put("length",fs.length());
				long time = file.lastModified();
				Date date = new Date(time);
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd E HH:mm");
				temp.put("time",sdf.format(date));
				temp.put("canRead",fs.canRead());
				temp.put("canWrite",fs.canWrite());
				temp.put("isHidden",fs.isHidden());
				fileList.add(temp);
			}
		}
		return fileList;
	}
	//filePath为带路径的文件名
	public static Map<String, Object>  readJsonFile(String filePath)
	{
		reader = null;
		content = null;
		try {
			reader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath),"UTF-8"));
			content = reader.lines().collect(Collectors.joining("\n"));
		}catch (IOException e) {
			return null;
		}finally {
			try {
				if (IsKit.isNotNull(reader)) {
					reader.close();
				}
			} catch (IOException e) {
				LogKit.error(e.getMessage());
			}
		}
		return JsonKit.json2Map_jackson(content);
	}

	/**用于读src/main/resources/static/目录下文件*/
	private static final String rootDir = "classpath:static" + CharsetKit.SYMBOL_BACK_SLASH;
	public static Map<String, Object> readJsonFileFromJar(String filePath)
	{
		reader = null;
		content = null;
		resource = new ClassPathResource(rootDir + filePath);
		try {
			reader = new BufferedReader(new InputStreamReader(resource.getInputStream(),"UTF-8"));
			content = reader.lines().collect(Collectors.joining("\n"));
		}catch (IOException e) {
			return null;
		}finally {
			try {
				if (IsKit.isNotNull(reader)) {
					reader.close();
				}
			} catch (IOException e) {
				LogKit.error(e.getMessage());
			}
		}
		return JsonKit.json2Map_jackson(content);
	}
	///////////////////////
	//获取目录下所有文件名
	public static List<String> getFilesName(String fielPath)
	{  
		List<String> fileList = new ArrayList<>(); 
		File file = new File(fielPath);
		if (!file.exists()) {
			return fileList;
		}
		File fa[] = file.listFiles();
		for (int i = 0; i < fa.length; i++) {
			File fs = fa[i];
			if (fs.isDirectory()){
			}
			else {
				fileList.add(fs.getName());
			}
		}
		return fileList;
	} 
	//获取目录下具有特定前缀的所有文件名
	public static List<String> getFilesName(String fielPath,String filePrefix)
	{  
		List<String> fileList = new ArrayList<>(); 
		File file = new File(fielPath);
		if (!file.exists()) {
			return fileList;
		}
		File fa[] = file.listFiles();
		for (int i = 0; i < fa.length; i++) {
			File fs = fa[i];

			if (fs.isFile() && fs.getName().startsWith(filePrefix)) {
				fileList.add(fs.getName());
			}	
		}
		return fileList;
	} 

	/**
	 * delete file
	 * @param path
	 * @param filename
	 */
	public static Boolean delFile(String path,String filename)
	{
		if (!(path.substring(path.length() - 1 )).equals(CharsetKit.FILE_SEPARATOR))
			path = path + CharsetKit.FILE_SEPARATOR;
		File file = new File(path + filename);

		if(file.exists()&&file.isFile()){
			return file.delete();
		}
		return false;
	}

	/**
	 * 删除文件
	 * @param filePath 文件
	 * @return
	 */
	public static boolean delFile(String filePath)
	{
		boolean flag = false;
		File file = new File(filePath);
		// 路径为文件且不为空则进行删除
		if (file.isFile() && file.exists())
		{
			file.delete();
			flag = true;
		}
		return flag;
	}

	//删除folderId目录下，具有前缀filePre的所有文件
	public static int delMultiFile(String folderId, String filePre)
	{
		int delNum = 0;
		//创建File对象,指向folderId目录
		File folder = new File(folderId);
		if (folder != null && folder.exists()) 
		{
			//folder.list();获取目录所有文件和路径,并以字符串数组返回
			File[] names = folder.listFiles(); 
			for (File f1 : names) {//遍历字符串数组
				if (f1.isFile() && f1.getName().startsWith(filePre)) {
					if(delFile(folderId,f1.getName())){
						++delNum;
					}
				}	
			}
		}
		return delNum;
	}

	public static boolean copy(MultipartFile mf, String folderId, String fileName)
	{
		boolean flag = true;
		File uploadFile = new File(folderId + fileName);
		try { 
			FileCopyUtils.copy(mf.getBytes(), uploadFile);  
		} catch (IOException e) { 
			flag = false;
		}
		return flag;
	}

	public static boolean mkdirs(String path)
	{
		boolean resultFlag = true;
		File dir = new File(path);
		//存在且为一个目录时isDirectory()返回true
		if(! dir.isDirectory()){
			dir.mkdir();
			resultFlag = dir.isDirectory();
		} 
		return resultFlag;
	}
	

	
	/**
	 * 输出指定文件的byte数组
	 *
	 * @param filePath 文件路径
	 * @param os 输出流
	 * @return
	 */
	public static void writeBytes(String filePath, OutputStream os) throws IOException
	{
		FileInputStream fis = null;
		try
		{
			File file = new File(filePath);
			if (!file.exists())
			{
				throw new FileNotFoundException(filePath);
			}
			fis = new FileInputStream(file);
			byte[] b = new byte[1024];
			int length;
			while ((length = fis.read(b)) > 0){
				os.write(b, 0, length);
			}
		}
		catch (IOException e){throw e;}
		finally{
			if (IsKit.isNotNull(os)){
				try{
					os.close();
				}
				catch (IOException e1){
					LogKit.info(e1);
				}
			}
			if (IsKit.isNotNull(fis)){
				try{
					fis.close();
				}
				catch (IOException e1){
					LogKit.info(e1);
				}
			}
		}
	}

	/**
	 *  将一个文件读入字节数组
	 */
	public static byte[] getBytesFromFile(File file)  
	{
		byte[] s = null;
		InputStream is = null;
		try {
			is = new FileInputStream(file);
			long length = file.length();
			if (length > Integer.MAX_VALUE) {
				throw new IOException(file.getName() + " is too large , break.");
			}
			s = new byte[(int) length];
			int offset = 0;
			int numRead = 0;
			while (offset < s.length && (numRead = is.read(s, offset, s.length - offset)) >= 0) {
				offset += numRead;
			}
			if (offset < s.length) {
				throw new IOException("Could not completely read file " + file.getName());
			}
		} catch (Exception e) {
			LogKit.info(e);
		}
		finally{
			if (IsKit.isNotNull(is)){
				try {
					is.close();
				} catch (IOException e) {
					LogKit.info(e);
				}
			}
		}
		return s;
	}
}
