/*************************************************************************************************
 * 프로그램명 : HttpDocRegist.java 프로그램설명 : 집계문서 등록자 작성자 : 강원중 작성일 : 2004.06.07 변경일 : 2003.11.30
 **************************************************************************************************/

package kr.co.kihyun.beans.totsys.doc;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
//import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
//import java.util.List;
//import java.util.Map.Entry;
import java.util.Set;

import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.co.kihyun.beans.entity.AcceptanceLimitStrategy;
import kr.co.kihyun.beans.entity.AccessAuth;
//import kr.co.kihyun.beans.entity.Board;
import kr.co.kihyun.beans.entity.Category;
import kr.co.kihyun.beans.entity.ExecutionCode;
import kr.co.kihyun.beans.entity.MDept;
import kr.co.kihyun.beans.entity.MUser;
import kr.co.kihyun.beans.entity.TotDoc;
import kr.co.kihyun.beans.entity.TotDocAppendType;
import kr.co.kihyun.beans.entity.TotDocProcess;
import kr.co.kihyun.beans.entity.TotDocType;
import kr.co.kihyun.beans.entity.TotItem;
import kr.co.kihyun.beans.entity.TotReport;
import kr.co.kihyun.beans.entity.TotReportProcess;
import kr.co.kihyun.beans.entity.TotTable;
import kr.co.kihyun.beans.entity.util.MPersistenceManager;
import kr.co.kihyun.beans.entity.util.PMF;
import kr.co.kihyun.beans.totsys.report.ReportUpdate;
import kr.co.kihyun.beans.user.GroupView;
import kr.co.kihyun.beans.user.HttpSSOLogin;
import kr.co.kihyun.io.FileUtil;
import kr.co.kihyun.lang.Encoder;
import kr.co.kihyun.lang.MInteger;
import kr.co.kihyun.lang.MLong;
import kr.co.kihyun.lang.MString;
import kr.co.kihyun.moumi.MoumiConfig;
import kr.co.kihyun.text.html.ServletUtil;
import kr.co.kihyun.text.html.TagFilter;
import org.datanucleus.ObjectManager;
import org.datanucleus.jdo.JDOPersistenceManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@WebServlet("/servlet/kr.co.kihyun.beans.totsys.doc.HttpSubDocRegist")
public class HttpSubDocRegist extends HttpServlet {

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;
	private static final Logger LOG = LoggerFactory.getLogger(HttpSubDocRegist.class);

	@Override
	public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		res.setContentType("text/html;charset=UTF-8");
		if (req.getMethod().equals("HEAD"))
			return;
		PrintWriter out = res.getWriter();

		/*********** User HttpLogin check ***********/
		if (!HttpSSOLogin.isLogin(req)) {
			String connURL = "location='/totsys/login/login.jsp';";
			out.println(ServletUtil.getJavaScript(connURL));
			return;
		}

		/********** session내의 userId **********/
		String usID = HttpSSOLogin.getLoginID(req);
		String dpID = HttpSSOLogin.getDeptID(req);

		/********** parameter value **********/
		String docName = Encoder.toJava(req.getParameter("docName"));
		String stDate = Encoder.toJava(req.getParameter("stDate"));
		String stTime = Encoder.toJava(req.getParameter("stTime"));
		String edDate = Encoder.toJava(req.getParameter("edDate"));
		String edTime = Encoder.toJava(req.getParameter("edTime"));
		int execNum = MInteger.parseInt(req.getParameter("execNum"));
		String execDate = MString.checkNull(req.getParameter("execDate"));
		String acceptanceLimitStrategy = Encoder.toJava(req.getParameter("acceptanceLimitStrategy"));
		String prss = Encoder.toJava(req.getParameter("prss"));
		Long submitLimit = MLong.parseLong(req.getParameter("submitLimit"), Long.MAX_VALUE);
		String title = Encoder.toJava(req.getParameter("title"));
		String contents = Encoder.toJava(req.getParameter("notify"));
		//String svrFilenames = URLDecoder.decode(MString.checkNull(req.getParameter("svrFilenames")), "UTF-8");

                String svrFilenames=Encoder.toJava(MString.checkNull(req.getParameter("svrFilenames")));
                svrFilenames = URLDecoder.decode(svrFilenames, "UTF-8");


		String deptIDs = Encoder.toJava(req.getParameter("deptIDs"));
		int accAuth = MInteger.parseInt(req.getParameter("accAuth"), 0);// 집계문서 접근권한
		// String docForm = Encoder.toJava(req.getParameter("docForm"));
		String docForm = Encoder.toJava(TagFilter.convertSingle(req.getParameter("copyForm")));

		Long reportID = new Long(MInteger.parseInt(req.getParameter("reportID")));

		stDate += " " + stTime + ":00:00";
		edDate += " " + edTime + ":00:00";

		Date startDate, endDate;
		startDate = endDate = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			startDate = sdf.parse(stDate);
			endDate = sdf.parse(edDate);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		String userIDs = Encoder.toJava(req.getParameter("userIDs"));
		String deptTypes = Encoder.toJava(req.getParameter("deptTypes"));

		String handyName = Encoder.toJava(MString.checkNull(req.getParameter("handyName")));
		int totRange = MInteger.parseInt(MString.checkNull(req.getParameter("totRange")), 1);

		String[] deptIDList = deptIDs.split(",");
		String[] typeList = deptTypes.split(",");

		MDept userDept = null;
		MUser mUser = null;
		TotDoc repDoc = null;
		TotReport totReport = null;
		PersistenceManager pm = new MPersistenceManager(PMF.get().getPersistenceManager());
		Transaction tx = pm.currentTransaction();
		ObjectManager om = ((JDOPersistenceManager) tx.getPersistenceManager()).getObjectManager(); // jeus 6 proplem
		try {
			tx.begin();
			userDept = pm.getObjectById(MDept.class, dpID);
			mUser = pm.getObjectById(MUser.class, usID);
			totReport = pm.getObjectById(TotReport.class, reportID);
			repDoc = totReport.getTotDoc();

			int all = typeList.length;
			StringBuilder dts = new StringBuilder();
			StringBuilder uss = new StringBuilder();

			for (int a = 0; a < all; a++) {
				if (typeList[a].equals("user")) {
					if (uss.toString().length() == 0) {
						uss.append(deptIDList[a]);
					} else {
						if (!uss.toString().contains(deptIDList[a])) {
							uss.append(",");
							uss.append(deptIDList[a]);
						}
					}
				} else if (typeList[a].equals("group")) {
					if (new GroupView().getUserUserDeptUserID(deptIDList[a]).length() != 0) {
						if (uss.toString().length() == 0) {
							uss.append(new GroupView().getUserUserDeptUserID(deptIDList[a]));
						} else {
							if (!uss.toString().contains(new GroupView().getUserUserDeptUserID(deptIDList[a]))) {
								uss.append(",");
								uss.append(new GroupView().getUserUserDeptUserID(deptIDList[a]));
							}
						}
					}

					if (new GroupView().getUserDeptDeptID(deptIDList[a]).length() != 0) {
						if (dts.toString().length() == 0) {
							dts.append(new GroupView().getUserDeptDeptID(deptIDList[a]));
						} else {
							if (!dts.toString().contains(new GroupView().getUserDeptDeptID(deptIDList[a]))) {
								dts.append(",");
								dts.append(new GroupView().getUserDeptDeptID(deptIDList[a]));
							}
						}
					}
				} else {
					if (dts.toString().length() == 0) {
						dts.append(deptIDList[a]);
					} else {
						if (!dts.toString().contains(deptIDList[a])) {
							dts.append(",");
							dts.append(deptIDList[a]);
						}
					}
				}
			}

			deptIDs = dts.toString();
			userIDs = uss.toString();
			if (docForm == null) {
				out.println(ServletUtil.alert(TotDocType.FORM_DOC + MoumiConfig.getMessageBundle().getString("moumi.message.popup.notTableReConfirm")));
				out.println(ServletUtil.redirect("/totsys/totper/mydocbox/regbox/sub_doc_regist.jsp?reportID="
						+ reportID));
			} else {
			}

			SimpleDateFormat execDateFormat = new SimpleDateFormat("yyyy-MM-dd");
			ExecutionCode execCode = null;
			if (execNum > 0 && !MString.isNull(execDate))
				execCode = new ExecutionCode(mUser.getUpperDept(pm).getName(), execNum, execDateFormat.parse(execDate));
			TotDoc newDoc = docRegist(pm, docName, execCode, handyName, mUser, startDate, endDate,
					AccessAuth.asAccessAuth(accAuth), TotDoc.TotRange.asTotRange(totRange), repDoc, userDept,
					acceptanceLimitStrategy, submitLimit, prss, repDoc.getAppendType());



                        title=docName;

            kr.co.kihyun.beans.entity.Board mBoard = new kr.co.kihyun.beans.entity.Board(title);
			mBoard.setUser(mUser);
			//mBoard.setContents(repDoc.getBoard().getContents());
            mBoard.setContents(contents);
			mBoard.setTotDoc(newDoc);
			mBoard.setCategory(pm.getObjectById(Category.class, Category.ID_TOT_DOC_COMMENT));
			LOG.debug("ID: {}, GROUP_ID: {}, REP_LEVEL: {}, STEP: {}, TITLE: {}, WRITE_DATE: {}",
					new Object[] {mBoard.getId(), mBoard.getCategory(), mBoard.getRepLevel(), mBoard.getStep(),
					mBoard.getTitle(), mBoard.getWriteDate()});

            FileUtil.putInFiles(svrFilenames, mBoard);


//                      연계등록시 자료를 수정(요구사항) 하지만 아래 내용때문에 상위기관에서 입력요령을 그대로 받아와서 셋아기때문에 그것을 지우고 위에 파일을 새로 넣음
//			for (Entry<String, List<Byte>> entry : repDoc.getAttachments().entrySet())
//			mBoard.addAttachment(entry.getKey(), entry.getValue());

			pm.makePersistent(mBoard);
			FileUtil.getBoardAttachmentsFileNames(mBoard.getId(), req,true);
			// succNum += new TableUpdate().insert(newDoc, repDoc);
			LOG.debug("repDoc: {}", repDoc);
			LOG.debug("rep tables: {}", repDoc.getTotTables());
			LOG.debug("rep items: {}", repDoc.getTotItems());
			LOG.debug("rep reports: {}", repDoc.getTotReports());
			TotTable masterTable = repDoc.getTotTables().iterator().next();
			TotTable totTable = new TotTable(newDoc);
			totTable.setName(masterTable.getName());
			totTable.setNote(masterTable.getNote());
			totTable.setTypes(masterTable.getTypes());
			totTable.setType(masterTable.getType());
			pm.makePersistent(totTable);

			// succNum += tableRegist(newDocID, repDocID, docForm);

			for(Iterator<TotItem> itemIter = repDoc.getTotItems().iterator(); itemIter.hasNext(); ) {
				TotItem sourceItem = itemIter.next();
				TotItem targetItem = new TotItem(newDoc);

				targetItem.setNum(sourceItem.getNum());
				targetItem.setTableNum(sourceItem.getTableNum());
				targetItem.setName(sourceItem.getName());
				targetItem.setDescription(sourceItem.getDescription());
				targetItem.setInputSize(sourceItem.getInputSize());
				targetItem.setExpr(sourceItem.getExpr());
				targetItem.setType(sourceItem.getType());
				targetItem.setColNum(sourceItem.getColNum());
				targetItem.setRowNum(sourceItem.getRowNum());

				pm.makePersistent(targetItem);
			}

			// 보고기관 입력
			// succNum += reportRegist(newDocID, newTableNum, deptIDs);
			String[] stringDeptIDArray = deptIDs.split(",");

                        //v2 23.정수형 오버플로우 (배열인덱스)_CWE-190 : Update by YOUNGJUN,CHO
                        if (stringDeptIDArray.length > 0) {
                            String[] longDeptIDArray = new String[stringDeptIDArray.length];
                            System.arraycopy(stringDeptIDArray, 0, longDeptIDArray, 0, stringDeptIDArray.length);
                            new ReportUpdate().deptUserInsert(pm, newDoc, totTable, longDeptIDArray);

                            // 보고기관 업(집계된 문서의 상위 보고 기관)
                            totReport.setSlaveTotDoc(newDoc);
                            totReport.setUser(mUser);
                            totReport.setProcess(TotReportProcess.TEMP);
                            //20110803 LJH
                            totReport.setDept(mUser.getUpperDept(pm));
                            totReport.setRepTotDoc(repDoc);

                            pm.makePersistent(totReport);

                            Set<TotReport> slaveReportList = newDoc.getTotReports();
                            for (TotReport slaveReport : slaveReportList)
                                    slaveReport.setRepTotDoc(repDoc);
                            pm.makePersistentAll(slaveReportList);

                            LOG.debug("commit");
                            om.postCommit(); // jeus 6 problem
                            tx.commit();
                            out.println(ServletUtil.alert(MoumiConfig.getMessageBundle().getString("moumi.message.popup.newSubdoc")));
    //			out.println(ServletUtil.redirect("/totsys/totper/mydocbox/prssbox/doc_list.jsp?docType=PRSS"));
                            out.println(ServletUtil.redirect("/totsys/repoper/mydocbox/tempbox/report_list.jsp?reportType=TEMP"));
                        }
			//================================================

		} catch (Exception e) {
			out.println(ServletUtil.alert(MoumiConfig.getMessageBundle().getString("moumi.message.popup.notRegistReConfirm")));
                        //v2. 9.크로스사이트 스크립트 (PrintWrier) : Update by KWON,HAN
//			out.println(ServletUtil.redirect("/totsys/totper/mydocbox/regbox/sub_doc_regist.jsp?reportID=" + reportID));

                        // 수정 : 외부 입력값 필터링
                        String callbackFunc = "/totsys/totper/mydocbox/regbox/sub_doc_regist.jsp?reportID=" + reportID;
                        String filtered_callbackFunc = callbackFunc.replaceAll("<","").replaceAll(">","");
                        LOG.debug("v2 9.크로스사이트 스크립트 (PrintWrier) : HttpSubDocRegist.doPost() filtered_callbackFunc={}, Not Test", filtered_callbackFunc);
                        out.println(ServletUtil.redirect(filtered_callbackFunc));
                        //============================================================

			e.printStackTrace();
		} finally {
			if (tx.isActive()) {
				tx.rollback();
			}
			pm.close();
		}
	}

	private TotDoc docRegist(PersistenceManager pm, String docName, ExecutionCode execCode, String handyName,
			MUser mUser, Date stDate, Date edDate, AccessAuth accAuth, TotDoc.TotRange totRange, TotDoc repDoc,
			MDept mDept, String acceptanceLimitStrategy, Long submitLimit, String prss, TotDocAppendType appendType) {
		TotDoc newDoc = new TotDoc(docName, mDept, repDoc.getForm());
		newDoc.setUser(mUser);
		newDoc.setExecutionCode(execCode);
		newDoc.setHandyName(handyName);
		newDoc.setStartDate(stDate);
		newDoc.setEndDate(edDate);
		newDoc.setAccessAuth(accAuth);
		newDoc.setTotRange(totRange);
		newDoc.setMasterTotDoc(repDoc);
		newDoc.setDept(mUser.getUpperDept(pm));
		newDoc.setAppendType(appendType);
		AcceptanceLimitStrategy acptLimitStrategy = AcceptanceLimitStrategy.create(acceptanceLimitStrategy, submitLimit);
		acptLimitStrategy.setProcess(TotDocProcess.valueOf(prss));
		newDoc.setAcceptanceLimitStrategy(acptLimitStrategy);
		pm.makePersistent(newDoc);

		return newDoc;
	}
}
