package nccloud.web.hrhi.psndoc.action;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import nc.bs.framework.common.RuntimeEnv;
import nc.bs.logging.Logger;
import nc.bs.pub.filesystem.IAttachManageConst;
import nc.itf.uap.IUAPQueryBS;
import nc.jdbc.framework.processor.BeanListProcessor;
import nc.ui.querytemplate.querytree.FromWhereSQL;
import nc.vo.hr.infoset.InfoSetVO;
import nc.vo.pub.filesystem.NCFileVO;
import nc.vo.pub.lang.UFDate;
import nccloud.framework.core.exception.ExceptionUtils;
import nccloud.framework.core.io.WebFile;
import nccloud.framework.core.json.IJson;
import nccloud.framework.service.ServiceLocator;
import nccloud.framework.web.action.itf.ICommonAction;
import nccloud.framework.web.container.IRequest;
import nccloud.framework.web.container.RequestJsonVO;
import nccloud.framework.web.json.JsonFactory;
import nccloud.pubitf.platform.attachment.IAttachmentService;
import nccloud.pubitf.platform.attachment.IFileStorageConst;
import nccloud.web.hr.pub.HRNccQueryHelper;
import uap.pub.fs.client.FileStorageClient;
import uap.pub.fs.domain.basic.FileHeader;
import uap.pub.fs.domain.ext.IFileStorageExt;

public class ZipDownLoadAction implements ICommonAction {
	
	@SuppressWarnings("unchecked")
	public Object doAction(IRequest request) {
		try {
			IJson gson = JsonFactory.create();
			RequestJsonVO requestJsonVO = new RequestJsonVO();
			IUAPQueryBS uapQueryBS = ServiceLocator.find(IUAPQueryBS.class);
			IAttachmentService service = ServiceLocator.find(IAttachmentService.class);
			 
			Map<String, String[]> info = request.readParameters();
			//downloadModel：1-按条件，2-按信息集
			int downloadModel = Integer.valueOf(info.get("downloadModel")[0]);
			//groupModel：1-按人，2-按信息集
			int groupModel = Integer.valueOf(info.get("groupModel")[0]);
			String[] allpks = info.get("allpks");
			String downloadSearchModalValue = info.get("downloadSearchModalValue") == null ? null : ((String[])info.get("downloadSearchModalValue"))[0];
			
			String infosetPKs = info.get("infosetPKs") == null ? null : ((String[])info.get("infosetPKs"))[0];
			String[] infoSetPks = null;
			if(infosetPKs!=null) {
				infoSetPks = infosetPKs.split(",");
			}
			//查询信息集
			Map<String, InfoSetVO> infoSetVOMap = new HashMap<String, InfoSetVO>();
			StringBuilder tableInfoSql = new StringBuilder("select table_code, infoset_name,infoset_code, pk_field_code \n");
			tableInfoSql.append(" from hr_infoset").append("\n");
			tableInfoSql.append(" where pk_infoset_sort = '1001Z710000000002XPO'").append("\n");
			if(infoSetPks!=null){
				tableInfoSql.append(" and ").append(nc.vo.pf.pub.util.SQLUtil.buildSqlForIn(" pk_infoset ", infoSetPks)).append("\n");
			}
			List<InfoSetVO> infoSetVOList = (List<InfoSetVO>) uapQueryBS.executeQuery(tableInfoSql.toString(),new BeanListProcessor(InfoSetVO.class));
			for (InfoSetVO infoSetVO : infoSetVOList) {
				infoSetVOMap.put(infoSetVO.getInfoset_code(), infoSetVO);
			}
			
			Map<String,JSONArray> infosetCodeConditionJsonArrayMap = new HashMap<String,JSONArray>();
			JSONObject jsonSearchinfo = null;
            if(downloadModel==1 && downloadSearchModalValue!=null) {
            	//按条件下载
            	jsonSearchinfo = gson.fromJson(downloadSearchModalValue, JSONObject.class);
    			JSONObject querycondition = jsonSearchinfo.getJSONObject("querycondition");
    			JSONArray conditionJsonArray = querycondition.getJSONArray("conditions");
    			
    			for(int size=conditionJsonArray.size(),i=0;i<size;i++) {
    				JSONObject conditionJson = conditionJsonArray.getJSONObject(i);
    				String field = conditionJson.getString("field");
    				String infosetCode = null;
    				String[] fields = field.split("\\.");
    				if (fields.length == 1) {
    					infosetCode = "bd_psndoc";
    				} else {
    					infosetCode = fields[0];
    				}
    				JSONArray tmpConditionJsonArray = infosetCodeConditionJsonArrayMap.get(infosetCode);
    				if (tmpConditionJsonArray == null) {
    					tmpConditionJsonArray = new JSONArray();
    					infosetCodeConditionJsonArrayMap.put(infosetCode, tmpConditionJsonArray);
    				}
    				tmpConditionJsonArray.add(conditionJson);
    			}	
    		}
    			
			StringBuilder unionSql = new StringBuilder();
			StringBuilder sql = new StringBuilder();
			sql.append("select sm_pub_filesystem.filepath path,\n");
			sql.append("       sm_pub_filesystem.pk_doc,\n");
			sql.append("       psndoc.code        creator,\n");
			sql.append("       psndoc.name        isdoc,\n");
			sql.append("       tableName        filetype\n");
			sql.append("  from sm_pub_filesystem\n");
			sql.append(" inner join (");
			
			for (InfoSetVO infoSetVO : infoSetVOList) {
				String infosetCode = infoSetVO.getInfoset_code();
				String tableCode = infoSetVO.getTable_code();
				String pk_field_code = infoSetVO.getPk_field_code();
				String whereSql = null;
				String tableAlias = tableCode;
				
				JSONArray tmpConditionJsonArray = infosetCodeConditionJsonArrayMap.get(infosetCode);
				if(downloadModel==1 && tmpConditionJsonArray==null) {
					continue;
				}
				if(downloadModel==1 && tmpConditionJsonArray!=null) {
					jsonSearchinfo.getJSONObject("querycondition").put("conditions", tmpConditionJsonArray);
					JSONObject busiParamJson = new JSONObject();
					busiParamJson.put("busiParamJson", jsonSearchinfo);
					requestJsonVO.setBusiParamJson(jsonSearchinfo.toJSONString());
					
					request.setRequestJsonVO(requestJsonVO);
					request.setJson(busiParamJson.toJSONString());
					
					HRNccQueryHelper queryHelper = new HRNccQueryHelper(request);
					FromWhereSQL fromWhereSQL = queryHelper.getQueryScheme().getTableJoinFromWhereSQL();
					whereSql = fromWhereSQL.getWhere();
					tableAlias = fromWhereSQL.getTableAliasByAttrpath(infosetCode);
					tableAlias = tableAlias==null?infosetCode:tableAlias;
				}
    				
				
				if(unionSql.length()>0){
					unionSql.append("\n").append(" union ").append("\n");
				}
				unionSql.append("select ");
				unionSql.append("concat(");
				unionSql.append(pk_field_code);
				unionSql.append(",'/') as pk_psndoc_sub,");
				unionSql.append(" pk_psndoc, ");
				unionSql.append("'");
				unionSql.append(infosetCode);
				unionSql.append("'");
				unionSql.append(" tableName");
				unionSql.append(" from ");
				unionSql.append(tableCode);
				unionSql.append(" ");
				unionSql.append(tableAlias);
				if(whereSql!=null){
					unionSql.append(" where ");
					unionSql.append(whereSql);
	                if (infosetCode.equals("hi_psndoc_parttime")) {
	                    unionSql.append(" and ismainjob = 'N' ");
	                }else if (infosetCode.equals("hi_psnjob")) {
	                    unionSql.append(" and ismainjob = 'Y' ");
	                }
				}else{
					if (infosetCode.equals("hi_psndoc_parttime")) {
						unionSql.append(" where ");
	                    unionSql.append(" ismainjob = 'N' ");
	                }else if (infosetCode.equals("hi_psnjob")) {
	                	unionSql.append(" where ");
	                    unionSql.append(" ismainjob = 'Y' ");
	                }
				}
				
			}
			
			sql.append(unionSql);
			sql.append(" ) psndoc_sub ");
			sql.append("    on concat(substr(sm_pub_filesystem.filepath, 0, 20), '/') = psndoc_sub.pk_psndoc_sub");
			sql.append(" inner join (");
			sql.append("select bd_psndoc.pk_psndoc,bd_psndoc.code,bd_psndoc.name\n");
			sql.append("  from bd_psndoc\n");
			sql.append(" inner join hi_psnjob hi_psnjob\n");
			sql.append("    on bd_psndoc.pk_psndoc = hi_psnjob.pk_psndoc\n");
			sql.append(" where  \n");
			sql.append(nc.vo.pf.pub.util.SQLUtil.buildSqlForIn(" hi_psnjob.pk_psnjob ", allpks));
			sql.append(" \n) psndoc ");
			sql.append("    on psndoc.pk_psndoc = psndoc_sub.pk_psndoc\n");
			sql.append(" where sm_pub_filesystem.isfolder = 'n' ");
			
			List<NCFileVO> fileVOList = (List<NCFileVO>)uapQueryBS.executeQuery(sql.toString(), new BeanListProcessor(NCFileVO.class));
			
			// 压缩包名
			String nowDate = new UFDate().toStdString().replaceAll("-", "");
			long currentTimeMillis = System.currentTimeMillis();
			String zipFileName = "员工附件【"+(downloadModel==1?"条件下载":"信息集下载")+(groupModel==1?"按人分组":"按信息集分组")+"】"+nowDate+currentTimeMillis+".zip";
			String defaultPathPfxZip = File.separator + "hrhisubfiletempload" + File.separator + "appcode" + File.separator
					+ zipFileName;
			String prefixFilePathZip = RuntimeEnv.getInstance().getNCHome() + File.separator + "hotwebs"
					+ File.separator + "nccloud" + File.separator + "WEB-INF" + defaultPathPfxZip;
			// 在home里面生成zip文件
			File zipFile = new File(prefixFilePathZip);
			File filePath = zipFile.getParentFile();
			if (!filePath.exists()) {
				filePath.mkdirs();
			}
			OutputStream os = null;
			BufferedOutputStream bos = null;
			ZipOutputStream zos = null;
			
			try {
				os = new FileOutputStream(zipFile);
				bos = new BufferedOutputStream(os);
				zos = new ZipOutputStream(bos);
				for(NCFileVO ncFileVO:fileVOList){
					String pk_doc = ncFileVO.getPk_doc();
					String fileName = ncFileVO.getName();
					String tableName = ncFileVO.getFiletype();
					String psn_code = ncFileVO.getCreator();
					String psn_name = ncFileVO.getIsdoc();
					String folderName = null;
					String defaultType = null;
					InfoSetVO infoSetVO = infoSetVOMap.get(tableName);
					if(psn_code==null || psn_name==null || infoSetVO==null){
						continue;
					}
					if(groupModel==1){
						//按人分组
						folderName = psn_name+psn_code;
					}else{
						//按信息集分组
						folderName = infoSetVO.getInfoset_name();
					}
					
					fileName = psn_code+"-"+fileName;
					
					if (fileName != null && fileName.contains(".")) {
						defaultType = fileName.substring(fileName.lastIndexOf("."), fileName.length());
					}
					if (!fileName.contains(".")&& defaultType != null) {
						fileName = fileName + defaultType;
					}
					InputStream inStream = null;
					BufferedInputStream buffInStream = null;
					try {
						inStream = service.download("z", pk_doc, IFileStorageConst.Bucket);
						buffInStream = new BufferedInputStream(inStream);
						ZipEntry zipEntry = new ZipEntry(folderName + "\\" + fileName);
						zos.putNextEntry(zipEntry);
						int length = 0;
						byte[] buf = new byte[1024];
						while ((length = buffInStream.read(buf)) > 0) {
							zos.write(buf, 0, length);
						}
						zos.closeEntry();
					} catch (Exception ex) {
						Logger.error(ex.getMessage(), ex);
					} finally {
						if (buffInStream != null) {
							buffInStream.close();
						} else {
							if (inStream != null) {
								inStream.close();
							}
						}
					}
				}
			}catch (Exception ex) {
				Logger.error(ex.getMessage(), ex);
				ExceptionUtils.wrapException(ex);
			} finally {
				if (zos != null) {
					zos.close();
				} else {
					if (bos != null) {
						bos.close();
					} else if (os != null) {
						os.close();
					}
				}
			}
			
			// 上传服务器
			String downloadFilePath = null;
			try {
				FileInputStream input = new FileInputStream(prefixFilePathZip);
				try {
					FileHeader fileHeader = FileStorageClient.getInstance().uploadFile(IAttachManageConst.RIAMoudleID, zipFileName, input, false, new IFileStorageExt[0]);
					if (fileHeader != null) {
						downloadFilePath = fileHeader.getPath();
					}
				} catch (Exception ex) {
					Logger.error(ex.getMessage(), ex);
					ExceptionUtils.wrapException(ex);
				} finally {
					if (input != null) {
						input.close();
					}
				}

			} catch (Exception ex) {
				Logger.error(ex.getMessage(), ex);
				ExceptionUtils.wrapException(ex);
			}
			// 删除home里面的文件
			deleteFileOrFolders(prefixFilePathZip);
			// 下载
			InputStream in = service.download("z", downloadFilePath, IFileStorageConst.Bucket);
			//返回前端
			return new WebFile(zipFileName, in);
		}catch(Exception ex) {
			Logger.error(ex.getMessage(), ex);
			ExceptionUtils.wrapException(ex);
		}
		return null;
	}

	private void deleteFileOrFolders(String tarFilePath) {
		if (tarFilePath.endsWith("WEB-INF")) {
			return;
		}
		File file = new File(tarFilePath);
		String parentPath = file.getParent();
		if ((file.isFile()) && (file.exists())) {
			file.delete();
		}
		for (;;) {
			File parentDir = new File(parentPath);
			parentPath = parentDir.getParent();

			File[] files = parentDir.listFiles();
			if ((files != null) && (files.length != 0)) {
				break;
			}
			parentDir.delete();
			deleteFileOrFolders(parentPath);
		}
	}

}
