package cn.myapps.support.tray.action;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.net.URLDecoder;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;

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

import cn.myapps.authtime.common.dao.PersistenceUtils;
import cn.myapps.common.util.FileWriteUtil;
import cn.myapps.common.util.PropertyUtil;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;

/**
 * 断点续传
 * 
 * @author Happy
 * 
 */
public class BreakpointUploadServlet extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 4275252610690933584L;
	private static final int UPLOAD_ERROR_SERVER = -200;
	private static final int UPLOAD_SUCCESS = 200;
	private static final int UPLOAD_ERROR_NETWORK_DISCONNECT = 101;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		String action = req.getParameter("action");
		if ("queryUploadSize".equals(action)) {
			try {
				doQueryUploadSize(req, resp);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		try {
			doUpload(req, resp);
		} catch (Exception e) {
		}
	}

	public void doUpload(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		try {
			int state = 0;
			try {

				long offset = 0L;
				long fileLength = 0L;
				String path = null;
				String fileName = null;

				DiskFileItemFactory fac = new DiskFileItemFactory();
				BreakpointServletFileUpload upload = new BreakpointServletFileUpload(
						fac);
				upload.setHeaderEncoding("utf-8");
				List fileList = null;
				try {
					fileList = upload.parseRequest(request);
					if (upload.isDisconnect()) {// 客户端传输过程中断了连接
						state = UPLOAD_ERROR_NETWORK_DISCONNECT;
					}
				} catch (FileUploadException ex) {
					state = -100;
					throw ex;
				}

                Iterator<FileItem> iter = fileList.iterator();
				while (iter.hasNext()) {
					FileItem item = iter.next();
					if (item.isFormField()) {
						String fieldName = item.getFieldName();
						if (fieldName.equalsIgnoreCase("path")) {
							path = item.getString("UTF-8");
						}if (fieldName.equalsIgnoreCase("name")) {
							fileName = URLDecoder.decode(item.getString("UTF-8"),"UTF-8");
						}else if (fieldName.equalsIgnoreCase("offset")) {
							offset = Long.valueOf(item.getString("UTF-8"));
						} else if (fieldName.equalsIgnoreCase("fileLength")) {
							fileLength = Long.valueOf(item.getString("UTF-8"));
						}
					}

				}

				String realPath = PropertyUtil.getPath()
						+ File.separator;// 服务器目录的绝对路径
				String savePath = realPath + path; // 存放此文件的绝对路径

				Iterator<FileItem> it = fileList.iterator();

				while (it.hasNext()) {
					FileItem item = it.next();
					if (!item.isFormField()) {
						String name = item.getName();
						if (name == null || name.trim().equals("")) {
							continue;
						}
						// 临时文件名
						String tempPath = savePath + File.separator + fileName
								+ ".tmp";

						if (offset == 0) {
							File temp = new File(tempPath);
							if (temp.exists()) {
								temp.delete();
							}
							temp.createNewFile();
							temp = null;
						}

						RandomAccessFile raf = null;
						InputStream in = null;
						try {
							raf = new RandomAccessFile(tempPath, "rw");

							if (offset > 0) {
								raf.setLength(offset);
								raf.seek(offset);
							}

							byte[] b = new byte[1024];
							in = item.getInputStream();

							int nRead = 0;
							while ((nRead = in.read(b)) > 0) {
								raf.write(b, 0, nRead);
							}
							raf.close();

							// 文件完整上传后 修改临时文件名
							File temp = new File(tempPath);
							File f = new File(savePath+ File.separator + fileName);
							if (temp.exists()){// && temp.length() == fileLength) {
								if(f.exists()){
									f.delete();
								}
								temp.renameTo(new File(savePath+ File.separator + fileName));
								try {
									int i = fileName.lastIndexOf(".");
									String fullPath = savePath+ File.separator + fileName;
									String rootPath = PropertyUtil.getPath();
									FileWriteUtil.writeKmConvertTask(rootPath, UUID.randomUUID().toString(),fullPath);
									//2秒
									Thread.sleep(2000);
									//判斷生成pdf文件存不存在
									String pdfFullPath = fullPath.substring(0,fullPath.lastIndexOf(File.separator))+File.separator+"swf"+File.separator+fileName.substring(0, fileName.lastIndexOf("."))+".pdf";
									File pdfFile = new File(pdfFullPath);
									//30s文件没转完则停止转换
									int count=0;
									while(true){
										count++;
										Thread.sleep(1000);
										if(pdfFile.exists() && pdfFile.length()>0){
											break;
										}
										if(count>30){
											break;
										}
									}
								} catch (Exception e) {
									// TODO: handle exception
								}
								state = UPLOAD_SUCCESS;
							}
						} catch (Exception ee) {
							state = UPLOAD_ERROR_SERVER;
							throw ee;
						} finally {
							if (raf != null) {
								try {
									raf.close();
								} catch (Exception ex) {
									ex.printStackTrace();
								}
							}
							if (in != null) {
								try {
									in.close();
								} catch (Exception ex) {
									ex.printStackTrace();
								}
							}
						}
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			PrintWriter writer = getPrintWriter(request, response);
			writer.print(state);
			writer.flush();
			writer.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				PersistenceUtils.closeSessionAndConnection();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 生成SWF文件
	 * 
	 * @param fileType
	 *            文件扩展名
	 * @param path
	 *            文件路径
	 * @param uuid
	 *            id
	 */
	private void createSWF(final String fileType,final String path ,final String uuid){
		
		if ("doc".equals(fileType) || "docx".equals(fileType) || "xls".equals(fileType)
			|| "xlsx".equals(fileType) || "pdf".equals(fileType)
			|| "txt".equals(fileType) || "rtf".equals(fileType)
			|| "et".equals(fileType) || "ppt".equals(fileType)
			|| "pptx".equals(fileType)
			|| "dps".equals(fileType) || "pot".equals(fileType)
			|| "pps".equals(fileType) || "wps".equals(fileType)) {
			
			try {
				//生成文件任务
				String rootPath = PropertyUtil.getPath();
				FileWriteUtil.writeKmConvertTask(rootPath,uuid,path);
//				ConverterUtil.createSWF(uuid, path,  fileType);
			} catch (Exception e) {
				e.printStackTrace();
			}
			
			/*new Thread(new Runnable() {
				
				public void run() {
					try {
						ConverterUtil.createSWF(uuid, path,  fileType);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}).start();*/
			
			
		}
	}

	private void doQueryUploadSize(HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		String path = request.getParameter("path");
		String name = request.getParameter("name");

		String realPath = this.getServletConfig().getServletContext()
				.getRealPath("")
				+ File.separator + path;// 服务器目录的绝对路径
		String savePath = realPath; // 存放此文件的绝对路径
		String tempPath = savePath + File.separator + name + ".tmp";

		File file = new File(tempPath);

		if (file.exists()) {
			response.getWriter().print(file.length());
		} else {
			response.getWriter().print(0);
		}
	}

	private PrintWriter getPrintWriter(HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html; charset=utf-8");
		return response.getWriter();
	}

}
