package com.paic.pad.info.common.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.multipart.MultipartFile;

import com.paic.pad.info.common.dto.LabelValueDTO;

/**
 * 文件的上传和下载的工具类
 * 
 */
public class FileUtils {
	static Log logger = LogFactory.getLog(FileUtils.class);
	
	public static String RESULT              = "RESULT";// 校验结果
	public static String MESSAGE             = "MESSAGE";// 校验不通过
	public static String VALID_PASS          = "1";// 校验通过
	public static String VALID_NOT_PASS      = "0";// 校验不通过

	// 文件上传路径
	public static enum FILEPATHS {

		SUGGESTION_LOCAL_FILE_DIR("1", SystemConstant.SUGGESTION_LOCAL_FILE_DIR, "需求上报", SystemConstant.UPLOAD_FILE_ALLOW_SUFFIX, SystemConstant.UPLOAD_FILE_ALLOW_SIZE), // 需求上报路径
		EXPERTS_LOCAL_FILE_DIR("2", SystemConstant.EXPERTS_LOCAL_FILE_DIR, "专家咨询提问附件", SystemConstant.UPLOAD_FILE_ALLOW_SUFFIX, SystemConstant.UPLOAD_FILE_ALLOW_SIZE), // 专家咨询提问附件路径
		SCENE_LOCAL_FILE_DIR("3", SystemConstant.SCENE_LOCAL_FILE_DIR, "场景图片", SystemConstant.UPLOAD_SCENE_IMGFILE_ALLOW_SUFFIX, SystemConstant.UPLOAD_SCENE_IMGFILE_ALLOW_SIZE), // 场景图片上传路径
		SCENE_LOCAL_FILE_TMP_DIR("4", SystemConstant.SCENE_LOCAL_FILE_TMP_DIR, "临时文件", SystemConstant.UPLOAD_SCENE_IMGFILE_ALLOW_SUFFIX, SystemConstant.UPLOAD_SCENE_IMGFILE_ALLOW_SIZE), // 文件上传临时路径
		USERINFO_IMAGES_LOCAL_FILE_DIR("5", SystemConstant.USERINFO_IMAGES_LOCAL_FILE_DIR, " 用户头像", SystemConstant.UPLOAD_SCENE_IMGFILE_ALLOW_SUFFIX, SystemConstant.UPLOAD_SCENE_IMGFILE_ALLOW_SIZE), // 用户图片上传路径
		DATAEXPORT_TEMPLATE_LOCAL_FILE_DIR("6", SystemConstant.DATAEXPORT_TEMPLATE_LOCAL_FILE_DIR, "数据模板", SystemConstant.UPLOAD_FILE_ALLOW_SUFFIX, SystemConstant.UPLOAD_FILE_ALLOW_SIZE);// 导出数据模板

		private String typeKey;
		private String typeValue;
		private String typeDesc;
		private String allowSuffix;
		private String allowSize;

		public String getTypeKey() {
			return typeKey;
		}

		public void setTypeKey(String typeKey) {
			this.typeKey = typeKey;
		}

		public String getTypeValue() {
			return typeValue;
		}

		public void setTypeValue(String typeValue) {
			this.typeValue = typeValue;
		}

		public String getTypeDesc() {
			return typeDesc;
		}

		public void setTypeDesc(String typeDesc) {
			this.typeDesc = typeDesc;
		}

		public String getAllowSuffix() {
			return allowSuffix;
		}

		public void setAllowSuffix(String allowSuffix) {
			this.allowSuffix = allowSuffix;
		}

		public String getAllowSize() {
			return allowSize;
		}

		public void setAllowSize(String allowSize) {
			this.allowSize = allowSize;
		}

		public static List<LabelValueDTO> getTypes() {
			List<LabelValueDTO> results = new ArrayList<LabelValueDTO>();
			for (FILEPATHS val : FILEPATHS.values()) {
				LabelValueDTO labelValueDTO = new LabelValueDTO();
				labelValueDTO.setKey(val.getTypeKey());
				labelValueDTO.setValue(val.getTypeDesc());
				results.add(labelValueDTO);
			}
			return results;
		}

		public static FILEPATHS getFilePath(String typeKey) {
			FILEPATHS result = null;
			for (FILEPATHS val : FILEPATHS.values()) {
				if (StringUtils.equals(val.getTypeKey(), typeKey)) {
					result = val;
				}
			}
			return result;
		}

		private FILEPATHS(String typeKey, String typeValue, String typeDesc, String allowSuffix, String allowSize) {
			this.typeKey = typeKey;
			this.typeValue = typeValue;
			this.typeDesc = typeDesc;
			this.allowSuffix = allowSuffix;
			this.allowSize = allowSize;
		}

		@Override
		public String toString() { // 覆盖了父类Enum的toString()
			return super.toString() + "(" + typeKey + "," + typeValue + "," + typeDesc + ")";
		}
	}

	/**
	 * 上传文件 --
	 * 
	 * @param request
	 * @param file
	 * @param propPath
	 * @return 文件新名称
	 * @throws Exception
	 */
	public static String upload(MultipartFile file, String propPath, String umId) throws Exception {
		if (file == null) {
			return null;
		}
		String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
		String fileNameNew = umId + getFileNameNew() + "." + suffix;
		logger.info("文件上传--开始--文件名称为:" + propPath + File.separator + fileNameNew);
		File f = new File(propPath + File.separator + fileNameNew);
		file.transferTo(f);
		f.createNewFile();
		return fileNameNew;
	}

	public static void uploadFile(MultipartFile file, String propPath)
			throws Exception {
		if (file == null) {
			return;
		}
		String fileNameNew = file.getOriginalFilename();
		logger.info("文件上传--开始--文件名称为:" + propPath + File.separator + fileNameNew);
		File f = new File(propPath + File.separator + fileNameNew);
		file.transferTo(f);
		f.createNewFile();
	}

	/**
	 * 文件校验
	 * 
	 * @param file
	 * @param settingParam
	 * @return 校验结果及校验信息
	 * @throws Exception
	 */
	public static Map<String, Object> valid(MultipartFile file, Map<String, String> settingParam) throws Exception {
		if (file == null) {
			return null;
		}
		String message = "";
		String validpass = VALID_PASS;
		String allowSuffix = settingParam.get(SystemConstant.UPLOAD_FILE_ALLOW_SUFFIX) == null ? "" : settingParam.get(SystemConstant.UPLOAD_FILE_ALLOW_SUFFIX);
		String allowSizeTmp = settingParam.get(SystemConstant.UPLOAD_FILE_ALLOW_SIZE) == null ? "0" : settingParam.get(SystemConstant.UPLOAD_FILE_ALLOW_SIZE);

		if (file.getOriginalFilename().lastIndexOf(".") == -1) {
			message = "请上传允许格式的文件:" + allowSuffix;
			validpass = VALID_NOT_PASS;
		}
		else {
			String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
			double allowSize = Double.parseDouble(allowSizeTmp);
			int length = allowSuffix.toUpperCase().indexOf(suffix.toUpperCase());
			if (length == -1) {
				message = "请上传允许格式的文件:" + allowSuffix;
				validpass = VALID_NOT_PASS;
			}
			else if (file.getSize() > (allowSize * 1024 * 1024)) {
				message = "您上传的文件大小已经超出规定范围:" + allowSize + "M";
				validpass = VALID_NOT_PASS;
			}
		}

		Map<String, Object> result = new HashMap<String, Object>();
		result.put(MESSAGE, message);
		result.put(RESULT, validpass);
		return result;
	}

	/**
	 * 文件的下载
	 * 
	 * @param request
	 * @param response
	 * @param downLoadPath
	 * @throws Exception
	 */
	public static void download(HttpServletRequest request, HttpServletResponse response, String fileName, String path) throws Exception {
		response.setContentType("text/html;charset=UTF-8");
		request.setCharacterEncoding("UTF-8");
		String fileNameTmp = path + "/" + fileName;
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		
		try {
			File downloadFile = new File(fileNameTmp);
			long fileLength = downloadFile.length();
			response.setContentType("application/x-download");
			response.setHeader("Content-disposition", "attachment; filename=" + new String(fileName.getBytes("gbk"), "ISO8859-1"));
			response.setHeader("Content-Length", String.valueOf(fileLength));

			bis = new BufferedInputStream(new FileInputStream(fileNameTmp));
			bos = new BufferedOutputStream(response.getOutputStream());
			byte[] buff = new byte[2048];
			int bytesRead;
			while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
				bos.write(buff, 0, bytesRead);
			}
		}
		finally {
			if(bis != null) {
				bis.close();
			}
			
			if(bos != null) {
				bos.close();
			}
		}
	}

	/**
	 * 获取资讯内容
	 * 
	 * @param resourceUrl
	 * @return
	 * @throws Exception
	 */
	public static String getResourceContent(String resourceUrl) throws Exception {
		URL url = new URL(resourceUrl);
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setDoOutput(true);
		String contenttype = connection.getContentType();
		String charSet = getCharset(contenttype);
		BufferedReader br = null;
		StringBuilder result = null;
		InputStreamReader isr = new InputStreamReader(connection.getInputStream(), charSet);
		try {
		    br = new BufferedReader(isr);
			String str = null;
			result = new StringBuilder();
			while ((str = br.readLine()) != null) {
				result.append(str);
			}
		}
		catch (Exception e) {
			logger.error("获取资讯内容异常", e);
		}
		finally{
			if(br != null) {
				br.close();
			}
		}
		return result.toString();
	}

	/**
	 * 获取页面编码
	 * 
	 * @param str
	 * @return
	 */
	private static String getCharset(String str) {
		Pattern pattern = Pattern.compile("charset=.*");
		if (str == null) {
			return "UTF-8";
		}
		Matcher matcher = pattern.matcher(str);
		if (matcher.find()) {
			return matcher.group(0).split("charset=")[1];
		}
		return "UTF-8";
	}

	/**
	 * 检测网络资源是否存在 
	 * 
	 * @param strUrl
	 * @return
	 */
	public static boolean isNetFileAvailable(String strUrl) {
		InputStream netFileInputStream = null;
		try {
			URL url = new URL(strUrl);
			URLConnection urlConn = url.openConnection();
			netFileInputStream = urlConn.getInputStream();
			if (null != netFileInputStream) {
				return true;
			}
			else {
				return false;
			}
		}
		catch (IOException e) {
			return false;
		}
		finally {
			try {
				if (netFileInputStream != null) {
					netFileInputStream.close();
				}
			}
			catch (IOException e) {

			}
		}
	}

	/**
	 * 文档是否存在
	 * 
	 * @param strUrl
	 * @return
	 */
	public static boolean isFileAvailable(String strUrl) {
		File saveFile = new File(strUrl);
		if (saveFile.exists()) {
			return true;
		}
		else {
			return false;
		}
	}

	/**
	 * 获取新的文件名
	 * 
	 * @return
	 */
	private static String getFileNameNew() {
		SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		return fmt.format(new Date());
	}
	
	/**
	 * 删除文件 --
	 * 
	 * @param request
	 * @param filePath
	 * @throws Exception
	 */
	public static void delFile(String filePath) throws Exception {
		File delFile = new File(filePath);
		
		if (delFile.exists()) {
			delFile.delete();
		}
		
	}
	
	/**
	 * 删除多个文件 --
	 * 
	 * @param request
	 * @param filePath
	 * @throws Exception
	 */
	public static void delFileList(List<String> filePathList,String basePath) throws Exception {
		if(CommonUtils.listNotNull(filePathList)) {
			for (int i = 0; i < filePathList.size(); i++) {
				File delFile = new File(basePath + File.separator + filePathList.get(i));
				if (delFile.exists()) {
					delFile.delete();
				}
			}
		}
	}

	/**
	 * 复制文件 --
	 * 
	 * @param request
	 * @param temFilePath
	 * @param realFilePath
	 * @throws Exception
	 */
	public static void copyFile(String temFilePath, String realFilePath) throws Exception {
		int byteRead = 0;
		File oldfile = new File(temFilePath);
		InputStream inputStream = null;
		FileOutputStream fileOutputStream = null;
		
		try {
			if (oldfile.exists()) {
				inputStream = new FileInputStream(temFilePath);
				fileOutputStream = new FileOutputStream(realFilePath);
				byte[] buffer = new byte[2048];
				while ((byteRead = inputStream.read(buffer)) != -1) {
					fileOutputStream.write(buffer, 0, byteRead);
				}
			}
		}
		finally {
			if (inputStream != null) {
				inputStream.close();
			}

			if (fileOutputStream != null) {
				fileOutputStream.close();
			}
		}
		
	}
}