package com.easy.cms.servlet;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
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.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;

import com.easy.base.BaseServlet;
import com.easy.common.obj.Ajax;
import com.easy.files.FileList;
import com.easy.util.IdGen;

@WebServlet("/cms/file")
public class FileServlet extends BaseServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	

	protected void doGet(HttpServletRequest request, HttpServletResponse response) {
		doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) {
		String action = request.getParameter("action");
		try {
			if (StringUtils.isEmpty(action)) {
				index(request, response);
			} else if ("upload".equals(action)) {
				upload(request, response);
			} else if ("merge".equals(action)) {
				merge(request, response);
			}else if ("findList".equals(action)) {
				findList(request, response);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		// this.write(new ExtReturn(false, "找不到方法!"), response);
	}

	public void index(HttpServletRequest request, HttpServletResponse response) throws Exception {
		request.getRequestDispatcher(prefix + "file/index.jsp").forward(request, response);
	}

	// 上传文件存储目录
	private static final String UPLOAD_DIRECTORY = "upload";

	// 上传配置
	private static final int MEMORY_THRESHOLD = 1024 * 1024 * 10; // 10MB
	private static final int MAX_FILE_SIZE = 1024 * 1024 * 40; // 40MB
	private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; // 50MB

	public void upload(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String path = getServletContext().getRealPath(UPLOAD_DIRECTORY);
		DiskFileItemFactory factory = new DiskFileItemFactory();
		// 设置内存临界值 - 超过后将产生临时文件并存储于临时目录中
		factory.setSizeThreshold(MEMORY_THRESHOLD);
		// 创建一个文件上传解析器
		ServletFileUpload upload = new ServletFileUpload(factory);
		// 解决上传文件名的中文乱码
		upload.setHeaderEncoding("UTF-8");
		// 设置最大文件上传值
		upload.setFileSizeMax(MAX_FILE_SIZE);
		// 设置最大请求值 (包含文件和表单数据)
		upload.setSizeMax(MAX_REQUEST_SIZE);
		// 判断提交上来的数据是否是上传表单的数据
		if (!ServletFileUpload.isMultipartContent(request)) {
			return;
		}
		// 使用ServletFileUpload解析器解析上传数据，解析结果返回的是一个List<FileItem>集合，每一个FileItem对应一个Form表单的输入项
		List<FileItem> list = null;
		try {
			list = upload.parseRequest(request);
		} catch (FileUploadException e) {
			e.printStackTrace();
		}
		HashMap<String, String> map = new HashMap<String, String>();
		for (FileItem item : list) {
			if (item.isFormField()) {
				
				//表单数据
				String name = item.getFieldName();
				// 解决普通输入项的数据的中文乱码问题
				String value = item.getString("UTF-8");
				map.put(name, value);// 放入map集合
			} else {
				//文件上传
				File fileParent = new File(path + "/" + map.get("guid"));// 以guid创建临时文件夹
				System.out.println(fileParent.getPath());
				if (!fileParent.exists()) {
					fileParent.mkdir();
				}

				String filename = item.getName();
				if (filename == null || filename.trim().equals("")) {
					continue;
				}
				// 注意：不同的浏览器提交的文件名是不一样的，有些浏览器提交上来的文件名是带有路径的，如：
				// 处理获取到的上传文件的文件名的路径部分，只保留文件名部分
				filename = filename.substring(filename.lastIndexOf("\\") + 1);

				// 创建文件
				File file;
				if (map.get("chunks") != null) {
					file = new File(fileParent, map.get("chunk"));
				} else {
					file = new File(fileParent, "0");
				}

				// copy
				FileUtils.copyInputStreamToFile(item.getInputStream(), file);
			}
		}
	}

	public void merge(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String path = request.getSession().getServletContext().getRealPath(UPLOAD_DIRECTORY);

		String guid = request.getParameter("guid");
		int chunks = Integer.parseInt(request.getParameter("chunks"));
		String fileName = request.getParameter("fileName");
		
		//进行文件合并
		File file = new File(path + "/" + guid);
		//判断分片数量是否正确
		if (file.list().length != chunks) {
			return;
		}
		/**
		 * 进行文件合并
		 */
		long longId = IdGen.nextLongId();
		String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
		String saveName = longId + "." + suffix;
		File newFile = new File(path + "/" + fileName);
		FileOutputStream outputStream = new FileOutputStream(newFile, true);// 文件追加写入

		byte[] byt = new byte[10 * 1024 * 1024];
		int len;
		for (int i = 0; i < chunks; i++) {
			FileInputStream temp = new FileInputStream(new File(path + "/" + guid + "/" + i));
			while ((len = temp.read(byt)) != -1) {
				outputStream.write(byt, 0, len);
			}
			temp.close();
		}
		/**
		 * 当所有追加写入都写完 才可以关闭流
		 */
		outputStream.close();
		// 最后删除分片的文件夹
		FileUtils.deleteDirectory(file);
		this.write(new Ajax(true, "保存成功"), response);
	}
	public void findList(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String path = getServletContext().getRealPath(UPLOAD_DIRECTORY);
		List<String> files = FileList.list(path, UPLOAD_DIRECTORY);
		request.setAttribute("files", files);
		request.getRequestDispatcher(prefix + "file/list.jsp").forward(request, response);
	}

	public void delete(HttpServletRequest request, HttpServletResponse response) {
		
		
		String uploadPath = getServletContext().getRealPath("/");
		//FileUtils.deleteQuietly(new File(uploadPath + video.getfUrl()));
	}

}
