/**
 * Company Name : 中贸促信息技术有限责任公司
 * Project Name:project
 * File Name:UploadFileController.java
 * Package Name:ccpit.base.controller
 * Date:2015年10月13日下午2:38:00
 * Copyright (c) 2015, dingwei@ccpit.org All Rights Reserved.
 *
 */

package ccpit.base.controller;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

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

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang.StringUtils;
import ccpit.base.utils.OSinfoUtil;
import ccpit.base.utils.ReadConfigUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * ClassName:UploadFileController <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason: TODO ADD REASON. <br/>
 * Date: 2015年10月13日 下午2:38:00 <br/>
 * 
 * @author dingwei
 * @version
 * @since JDK 1.6
 * @see
 */
@Controller
@RequestMapping("base/upload")
public class UploadFileController extends BaseController {
	public static final String File_maxSize = ReadConfigUtil.getPlatformConfig("file.maxSize");
	private static final List<String> allowedContentTypes = Arrays.asList(
			"image/jpeg", "image/png", "image/gif", "image/bmp", "image/x-png","application/vnd.ms-excel");
	private static final List<String> allowedInvestContentTypes = Arrays
			.asList("image/jpeg", "application/msword", "image/png",
					"image/gif", "image/bmp", "image/x-png","application/kswps",
					"application/kset","application/pdf","application/ksdps",
					"application/vnd.openxmlformats-officedocument.wordprocessingml.document");
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
	private SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM");
	public static final String DOWNLOADPATH = ReadConfigUtil.getPlatformConfig("system.downloadPath"); // 文件下载路径
	
	public static String UPLOADFILEPATH = "";
	
	static {
		if(OSinfoUtil.isWindow()){
			UPLOADFILEPATH = ReadConfigUtil.getPlatformConfig("system.uploadFilePath.dev");  //文件上传路径 开发环境
		}
		if(OSinfoUtil.isLinux()){
			UPLOADFILEPATH = ReadConfigUtil.getPlatformConfig("system.uploadFilePath.pro");  //文件上传路径 生产环境
		}
	}

	@RequestMapping("ckupload")
	public void ckUploadFile(HttpServletRequest request,
			HttpServletResponse response) {
		// response.setHeader("X-Frame-Options", "SAMEORIGIN");
		String CKEditorFuncNum = request.getParameter("CKEditorFuncNum");
		String fileName = request.getContextPath() + uploadFile(request);
		PrintWriter out;
		String s = "<script type=\"text/javascript\">window.parent.CKEDITOR.tools.callFunction("
				+ CKEditorFuncNum + ", '" + fileName + "');</script>";
		try {
			out = response.getWriter();
			out.print(s);
			out.flush();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@RequestMapping("/progress")
	@ResponseBody
	public Object progress(HttpServletRequest request,
			HttpServletResponse response) {
		Object obj = request.getSession().getAttribute("UPLOAD_PERCENTAGE");
		if (obj == null)
			return 100.0d;
		return obj;
	}

	@RequestMapping("/uploadFile")
	@ResponseBody
	public Object uploadFile(HttpServletRequest request,
			HttpServletResponse response) {
		Map<String, Object> result = new HashMap<String, Object>();
		String file = uploadFile(request);
		result.put("message", !StringUtils.isEmpty(file));
		result.put("fileSavePath", file);
		return result;
	}

	/**
	 * uploadFile:该方法作为投资上传附件的方法 <br/>
	 *
	 * @author liyang
	 * @param request
	 * @param response
	 * @return Date:2016年4月22日上午8:45:29
	 * @since JDK 1.6
	 */
	@RequestMapping("/uploadFileInvest")
	@ResponseBody
	public Object uploadFileInvest(HttpServletRequest request,
			HttpServletResponse response) {
		Map<String, Object> result = new HashMap<String, Object>();
		Map m1 = InvestStudyuploadFile(request);
		if (m1 == null) {
			result.put("message", 0);
		} else {
			result.put("message",!StringUtils.isEmpty((String) m1.get("filePath")));
			result.put("fileSavePath", DOWNLOADPATH+(String) m1.get("filePath"));
			result.put("fileName", (String) m1.get("fileName"));
		}
		return result;
	}

	/**
	 * 保存上传图片实现方案:在uploadFile总目录下面按照月份创建目录,当其中某一个月的图片保存文件夹大小超过200M,再在该月目录下面创建
	 * 以当天日期命名的目录用以保存上传图片
	 */
	private String uploadFile(HttpServletRequest request) {
		// 需要返回的fileName
		String fileName = "";
		String fileName1 = "";
		String dateStr = sdf.format(new Date());
		String monthStr = sdf1.format(new Date());
		String realPath = UPLOADFILEPATH + "/uploadFile" + "/" + monthStr + "/";
		String rp = "/uploadFile/" + monthStr + "/";
		DiskFileItemFactory factory = new DiskFileItemFactory();
		// Configure a repository (to ensure a secure temp location is used)
		ServletContext servletContext = request.getSession()
				.getServletContext();
		File repository = (File) servletContext
				.getAttribute("javax.servlet.context.tempdir");
		factory.setRepository(repository);
		ServletFileUpload upload = new ServletFileUpload(factory);
		// 设置单个文件的大小
		upload.setFileSizeMax(20 * 1024 * 1024);
		// 设置总共文件的大小
		upload.setProgressListener(new UploadListener(request));
		try {
			List<FileItem> items = upload.parseRequest(request);
			System.out.println("**********************************************");
			System.out.println(items.size());
			System.out.println("**********************************************");
			for (FileItem item : items) {
				String type = item.getContentType();
				if (type == null) {
					continue;
				}
				// 文件参数
				fileName = item.getName();
				File dir = null;
				if (allowedContentTypes.contains(type)) {
					// 文件大小
					long fileSize = (item.getSize() / (Integer
							.parseInt(File_maxSize) * 1024 * 1024));
					if (fileSize < 1) {
						String str = getRandomString(15);
						List<String > types = new ArrayList<String>();
						types.add("jpg");
						types.add("jpeg");
						types.add("png");
						types.add("doc");
						types.add("docx");
						types.add("xls");
						types.add("xlsx");
						types.add("pdf");
						if(validateFileSuffix(fileName,types)){
							fileName1 = dateStr + "_" + str + "."+  fileName.substring(fileName.lastIndexOf(".")+1,fileName.length()).toLowerCase();
						dir = new File(realPath);
						}
						if (dir.exists()) {
							double dirLong = getUploadFileSize(dir);
							// 图片存放文件夹大小超过200M 将重新创建新的图片存放文件夹
							if (dirLong >= 200) {
								dir = new File(realPath + "/" + dateStr);
								dir.mkdir();
								rp += dateStr + "/";
							}
						} else {
							dir.mkdirs();
						}
						File f = new File(dir, fileName1);
						if (f.exists()) {
							f.delete();
						}
						f.createNewFile();
						// 保存
						item.write(f);
						return rp + fileName1;
					}
				}
			}
		} catch (FileUploadException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static String getRandomString(int length) { // length表示生成字符串的长度
		String base = "abcdefghijklmnopqrstuvwxyz0123456789";
		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < length; i++) {
			int number = random.nextInt(base.length());
			sb.append(base.charAt(number));
		}
		return sb.toString();
	}

	// 读取上传文件目录大小
	private static double getUploadFileSize(File dir) {
		// 判断文件是否存在
		if (dir.exists()) {
			// 如果是目录则递归计算其内容的总大小
			if (dir.isDirectory()) {
				File[] files = dir.listFiles();
				double size = 0;
				for (File f : files) {
					size += getUploadFileSize(f);
				}
				return size;
			} else {
				// 如果是文件则直接返回其大小,以“兆”为单位
				double size = (double) dir.length() / 1024 / 1024;
				return size;
			}
		} else {
			System.out.println("文件或者文件夹不存在,请检查路径是否正确!");
			return 0.0;
		}
	}

	private class UploadListener implements ProgressListener {
		private HttpServletRequest request;
		private DecimalFormat df = new DecimalFormat("#00.0");

		UploadListener(HttpServletRequest request) {
			this.request = request;
		}

		@Override
		public void update(long bytesRead, long bytesTotal, int items) {
			double percent = (double) bytesRead * 100 / (double) bytesTotal;
			request.getSession().setAttribute("UPLOAD_PERCENTAGE",
					df.format(percent));
		}

	}

	@RequestMapping("/uploadImage")
	@ResponseBody
	public void uploadImage(HttpServletRequest request,
			HttpServletResponse response) {
		String CKEditorFuncNum = request.getParameter("CKEditorFuncNum");
		String fileName = request.getContextPath() + uploadFile(request);
		PrintWriter out;
		String serverIp = "http://www.co.ccpit.org";
		String s = "<script type=\"text/javascript\">window.parent.CKEDITOR.tools.callFunction("
				+ CKEditorFuncNum
				+ ", '"
				+ serverIp
				+ fileName
				+ "');</script>";
		try {
			out = response.getWriter();
			out.print(s);
			out.flush();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * InvestStudyuploadFile:该方法用来处理上传附件并且返回原文件名. <br/>
	 *
	 * @author liyang
	 * @param request
	 * @return map Date:2016年4月22日上午8:40:02
	 * @since JDK 1.6
	 */
	private Map<String, String> InvestStudyuploadFile(HttpServletRequest request) {
		// 需要返回的fileName
		Map<String, String> map = new HashMap<String, String>();
		String fileName = "";
		String fileName1 = "";
		String dateStr = sdf.format(new Date());
		String monthStr = sdf1.format(new Date());
		String realPath = UPLOADFILEPATH + "/uploadFile" + "/" + monthStr + "/";
		String rp = "/uploadFile/" + monthStr + "/";
		DiskFileItemFactory factory = new DiskFileItemFactory();
		// Configure a repository (to ensure a secure temp location is used)
		ServletContext servletContext = request.getSession()
				.getServletContext();
		File repository = (File) servletContext
				.getAttribute("javax.servlet.context.tempdir");
		factory.setRepository(repository);
		ServletFileUpload upload = new ServletFileUpload(factory);
		// 设置单个文件的大小
		upload.setFileSizeMax(Integer.parseInt(File_maxSize) * 1024 * 1024);
		// 设置总共文件的大小
		upload.setProgressListener(new UploadListener(request));
		try {
			List<FileItem> items = upload.parseRequest(request);
			for (FileItem item : items) {
				String type = item.getContentType();
				if (type == null) {
					continue;
				}
				// 文件参数
				fileName = item.getName();
				map.put("fileName", fileName);
				File dir = null;
				if (allowedInvestContentTypes.contains(type)) {
					// 文件大小
					long fileSize = (item.getSize() / (Integer
							.parseInt(File_maxSize) * 1024 * 1024));
					if (fileSize < 1) {
						String str = getRandomString(15);
						List<String > types = new ArrayList<String>();
						types.add("jpg");
						types.add("jpeg");
						types.add("png");
						types.add("doc");
						types.add("docx");
						types.add("xls");
						types.add("xlsx");
						types.add("pdf");
						if(validateFileSuffix(fileName,types)){
							fileName1 = dateStr + "_" + str + "."+  fileName.substring(fileName.lastIndexOf(".")+1,fileName.length()).toLowerCase();
						dir = new File(realPath);
						}
						if (dir.exists()) {
							double dirLong = getUploadFileSize(dir);
							// 图片存放文件夹大小超过200M 将重新创建新的图片存放文件夹
							if (dirLong >= 200) {
								dir = new File(realPath + "/" + dateStr);
								dir.mkdir();
								rp += dateStr + "/";
							}
						} else {
							dir.mkdirs();
						}
						File f = new File(dir, fileName1);
						if (f.exists()) {
							f.delete();
						}
						f.createNewFile();
						// 保存
						item.write(f);
						map.put("filePath", rp + fileName1); // 返回下载的路径
						return map;
					}
				}
			}
		} catch (FileUploadException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 
	 * validateFileSuffix:(验证文件后缀名是否符合要求). <br/>
	 * @author dingwei
	 * @param fileName
	 * @return
	 * @since JDK 1.6
	 */
	public boolean validateFileSuffix(String fileName,List<String> types){
		boolean accord = false;
		String suffix = fileName.substring(fileName.lastIndexOf(".")+1,fileName.length());
		suffix = suffix.toLowerCase();
		if(types.contains(suffix)){
			return true;
		}
		return accord;
	}
}