package com.ylcm.sys.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.UUID;

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

import com.ylcm.sys.common.*;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.ylcm.sys.aliyun.OSSUtil;
import com.ylcm.sys.aliyun.OssMultipartUtil;
import com.ylcm.sys.enums.PicUploadEnum;

import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;

@RequestMapping(value = "/file/*")
@Controller
@Slf4j
public class FileController {

	@RequestMapping(value="index.do")
	public String index(){
		return "uploadtest";
	}

	/**
	 * 分片上传rar
	 * @param id			分片id
	 * @param name			文件名称
	 * @param chunks		总分片数
	 * @param chunk			当前分片编号
	 * @param file			分片文件
	 * @param request
	 * @param response
	 * @return				上传文件服务器路径
	 * @throws Exception
	 */
	@RequestMapping(value = "upload_rar.do", produces = "application/json;charset=utf-8", method = { RequestMethod.POST })
	@ResponseBody
	public String test(Integer modal2, String id, String name, Integer chunks, Integer chunk, MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws Exception{
		JSONObject result = new JSONObject();
		result.put("code", Constants.CODE_FAIL);
		result.put("msg", Constants.MSG_FAIL);
		
		File parentFileDir = null;
		String filePath = "";
		// 所有分片都存在才说明整个文件上传完成
		boolean uploadDone = true;
		try {
			boolean isMultipart = ServletFileUpload.isMultipartContent(request);
			if (isMultipart) {
				
				if (".rar".equals(name.substring(name.indexOf("."))) || ".zip".equals(name.substring(name.indexOf(".")))) {
					chunks = Util.isNotNull(chunks) ? chunks:1;
					chunk = Util.isNotNull(chunk) ? chunk:0;
					
					// session中的参数设置获取是我自己的原因,文件名你们可以直接使用fileName,这个是原来的文件名
					String realname = name;// 转化后的文件名
					request.setAttribute("realname", realname);
					filePath = request.getSession().getServletContext().getRealPath("/") + "/fileupload/";// 文件上传路径
					// 临时目录用来存放所有分片文件
					String tempFileDir = filePath + id;
					//临时文件目录
					parentFileDir = new File(tempFileDir);
					if (!parentFileDir.exists()) {
						parentFileDir.mkdirs();
					}
					// 分片处理时，前台会多次调用上传接口，每次都会上传文件的一部分到后台
					File tempPartFile = new File(parentFileDir, realname + "_" + chunk + ".part");
					FileUtils.copyInputStreamToFile(file.getInputStream(), tempPartFile);
					
					// 是否全部上传完成
					for (int i = 0; i < chunks; i++) {
						File partFile = new File(parentFileDir, realname + "_" + i + ".part");
						if (!partFile.exists()) {
							uploadDone = false;
						}
					}
					// 所有分片文件都上传完成,将所有分片文件合并到一个文件中
					if (uploadDone) {
						// 得到 destTempFile 就是最终的文件
						File destTempFile = new File(filePath, realname);
						for (int i = 0; i < chunks; i++) {
							File partFile = new File(parentFileDir, realname + "_" + i + ".part");
							FileOutputStream destTempfos = new FileOutputStream(destTempFile, true);
							// 遍历"所有分片文件"到"最终文件"中
							FileUtils.copyFile(partFile, destTempfos);
							destTempfos.close();
						}
						// 删除临时目录中的分片文件
						FileUtils.deleteDirectory(parentFileDir);
					}
					
					result.put("code", Constants.CODE_SUCCESS);
					result.put("msg", Constants.MSG_SUCCESS);
				}else{
					result.put("msg", "请上传.rar压缩文件");
					uploadDone = false;
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
			uploadDone = true;
			throw e;
		} finally {
			// 临时文件创建失败
			if (uploadDone) {
				try {
					FileUtils.deleteDirectory(parentFileDir);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		result.put("filePath", filePath);
		result.put("fileName", name);
		return result.toString();
	}
	
	/**
	 * 解压rar，并上传到oss
	 * @param path				rar文件所在目录
	 * @param name				文件名
	 * @param key				前端用于获取进度的唯一标识
	 * @param modal				图片类型 1:媒体logo  2:品牌logo  3:品牌植入
	 * @param request
	 * @return
	 */
	@RequestMapping(value="oss_rar.do",produces="application/json;charset=utf-8")
	@ResponseBody
	public String unrarToOss(String path, String name, String key, Integer modal, HttpServletRequest request){
		JSONObject result = new JSONObject();
		result.put("code", Constants.CODE_FAIL);
		result.put("msg", Constants.MSG_FAIL);
		try {
			if(Util.isNotNull(path) && Util.isNotNull(name)){
				HttpSession session = request.getSession();
				/*标识开始解压rar*/
				session.setAttribute(key+"_unrar", 0);
				/*解压rar*/
				String suffix = name.split("\\.")[1];
				if ("rar".equals(suffix)) {
					RarUtil.unrar(path+name, path + name.substring(0, name.lastIndexOf(".")) , null);
				} else if ("zip".equals(suffix)) {
					ZipUncompress.zipUncompress(path+name, path + name.substring(0, name.lastIndexOf(".")));
				}
				/*标识完成解压rar*/
				session.setAttribute(key+"_unrar", 1);
				/*上传文件到oss*/
				MyThreadPool.getInstance().execute(new UploadFiles(path, key, name, session, modal));
				result.put("code", Constants.CODE_SUCCESS);
				result.put("msg", Constants.MSG_SUCCESS);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			log.info("删除--rar文件地址:"+path+name);
			File rar= new File(path+name);
			if(rar.exists()){
				rar.delete();
			}
		}
		
		return result.toString();
	}
	
	/**
	 * 单个图片上传
	 * @param modal				图片类型 0:产品 1:栏目 2:电视剧 3:媒体
	 * @param name				文件名称
	 * @param file				文件
	 * @param request
	 * @return
	 */
	@RequestMapping(value="upload_img.do", produces="application/json;charset=utf-8")
	@ResponseBody
	public String uploadImg(Integer modal, String name, MultipartFile file, HttpServletRequest request){
		String url = "";
		String uploadId = "";
		try {
			boolean isMultipart = ServletFileUpload.isMultipartContent(request);
			if (isMultipart) {
				String key = EnumHelperUtil.getOneByCode(PicUploadEnum.class, modal + "").getName();
				key += name;
				OssMultipartUtil util = new OssMultipartUtil();
				uploadId = util.upload(file, key, request);
				// 成功，恢复初始值（恢复初始值是为了不让这次上传影响其他的文件上传）
				util.restoreDefaultValues();
				url = Constants.PIC_BASE_URL + key;
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
		
		JSONObject result = new JSONObject();
		result.put("url", url);
		result.put("uploadId", uploadId);
		return result.toString();
	}
	
	/**
	 * 获取上传进度
	 * @param key			进度条id
	 * @param request
	 * @return
	 */
	@RequestMapping(value="progress.do",produces="application/json;charset=utf-8")
	@ResponseBody
	public String progress(String key, HttpServletRequest request){
		JSONObject result = new JSONObject();
		result.put("code", Constants.CODE_FAIL);
		result.put("msg", Constants.MSG_FAIL);
		result.put("progress", 0);
		try {
			Integer unrar = (Integer) request.getSession().getAttribute(key+"_unrar");
			
			Double progress = 0d;
			if(Util.isNotNull(unrar) && unrar == 1){
				progress = OSSUtil.getProgress(key, request);
				progress = progress*0.8 + 0.2;
			}
			result.put("code", Constants.CODE_SUCCESS);
			result.put("msg", Constants.MSG_SUCCESS);
			result.put("progress", progress*100);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result.toString();
	}
	
	/**
	 * 获取上传进度2
	 * @param key			进度条id
	 * @param request
	 * @return
	 */
	@RequestMapping(value="progress2.do",produces="application/json;charset=utf-8")
	@ResponseBody
	public String progress2(String key, HttpServletRequest request){
		JSONObject result = new JSONObject();
		result.put("code", Constants.CODE_FAIL);
		result.put("msg", Constants.MSG_FAIL);
		
		result.put("progress", 0);
		try {
			Double progress = OssMultipartUtil.getProgress(key, request);
			if (Util.isNotNull(progress)) {
				result.put("progress", progress);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result.toString();
	}
	
	/**
	 * 上传指定目录下的文件
	 * @author zhoucong
	 *
	 */
	class UploadFiles implements Runnable{
		private String target;				//目标目录
		private String key;					//上传oss目录
		private String pkey;				//进度条id
		private HttpSession session;		
		public UploadFiles(String target, String pkey, String name, HttpSession session, Integer modal) {
			this.target = target + name.substring(0,name.indexOf(".")) + "/";
			this.pkey = pkey;
			this.session = session;
			key =  EnumHelperUtil.getOneByCode(PicUploadEnum.class, modal + "").getName();
		}
		
		public void run() {
			OSSUtil.uploadFilesForDiv(target,key, pkey, session);
		}
	}
}
