/*********************************************************************************************************
 * 프로그램명 : Moumi.java 프로그램설명 : 프로젝트와 관련된 정보를 얻을수 있는 class 작성자 : (주)기현테크 작성일 : 2003.12.18 변경일 : 2003.11.30
 **********************************************************************************************************/

package kr.co.kihyun.moumi;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.ResourceBundle;

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManagerFactory;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.co.kihyun.beans.entity.util.ECrossSchemaOrganizer;

import kr.co.kihyun.beans.entity.util.PMF;
import kr.co.kihyun.beans.entity.util.SchemaOrganizer;
import kr.co.kihyun.db.DBPool;
import kr.co.kihyun.sync.OrgSynchronizer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class Moumi implements Filter {
	/**
	 *
	 */
	private static final long serialVersionUID = 1L;
	private static final Logger LOG = LoggerFactory.getLogger(Moumi.class);
	private OrgSynchronizer sync;

	/**
	 * @deprecated Use {@link MoumiConfig#getMessageBundle()} instead
	 */
	public static final ResourceBundle getMessageBundle() {
		return MoumiConfig.getMessageBundle();
	}

	public Moumi() {
	}

      //v2. 5.static final 필드 변조 가능성 : Update by KWON,HAN
      // public이라서 이미 다른 자바함수에서 이미 사용하고 있으므로 웹취약점의 해결책을 적용하지 아니함.
	/******** 집계문서 접근권한 상수값
	 * @deprecated Use {@link MoumiConfig#PER} instead********/
	@Deprecated
	public static final int PER = MoumiConfig.PER;
	/**
	 * @deprecated Use {@link MoumiConfig#DEPT} instead
	 */
	@Deprecated
	public static final int DEPT = MoumiConfig.DEPT;
	/**
	 * @deprecated Use {@link MoumiConfig#PART} instead
	 */
	@Deprecated
	public static final int PART = MoumiConfig.PART;
	/**
	 * @deprecated Use {@link MoumiConfig#ALL} instead
	 */
	@Deprecated
	public static final int ALL = MoumiConfig.ALL;

	/******** 사용자 권한 상수 정의
	 * @deprecated Use {@link MoumiConfig#REPOPER} instead*********/
	@Deprecated
	public static final int REPOPER = MoumiConfig.REPOPER; // 보고자
	/**
	 * @deprecated Use {@link MoumiConfig#SUB_TOTPER} instead
	 */
	@Deprecated
	public static final int SUB_TOTPER = MoumiConfig.SUB_TOTPER; // 집계자
	/**
	 * @deprecated Use {@link MoumiConfig#TOTPER} instead
	 */
	@Deprecated
	public static final int TOTPER = MoumiConfig.TOTPER; // 상위집계자
	/**
	 * @deprecated Use {@link MoumiConfig#PART_REPOADM} instead
	 */
	@Deprecated
	public static final int PART_REPOADM = MoumiConfig.PART_REPOADM; // 기관보고관리자
	/**
	 * @deprecated Use {@link MoumiConfig#REPOADM} instead
	 */
	@Deprecated
	public static final int REPOADM = MoumiConfig.REPOADM; // 보고관리자
	/**
	 * @deprecated Use {@link MoumiConfig#SUB_TOTADM} instead
	 */
	@Deprecated
	public static final int SUB_TOTADM = MoumiConfig.SUB_TOTADM; // 기관집계관리자
	/**
	 * @deprecated Use {@link MoumiConfig#SUB_SYSADM} instead
	 */
	@Deprecated
	public static final int SUB_SYSADM = MoumiConfig.SUB_SYSADM; // 기관시스템관리자
	/**
	 * @deprecated Use {@link MoumiConfig#TOTADM} instead
	 */
	@Deprecated
	public static final int TOTADM = MoumiConfig.TOTADM; // 집계관리자
	/**
	 * @deprecated Use {@link MoumiConfig#SYSADM} instead
	 */
	@Deprecated
	public static final int SYSADM = MoumiConfig.SYSADM; // 시스템관리자
      //==========================================================


      //v2. 5.static final 필드 변조 가능성 : Update by KWON,HAN
      //private는 같은 클래스 내에서만 호출이 가능하므로 접근제한이 없는 public으로 하고 final을 사용하지 않는다
      //따라서 public static final  을 public static 으로 변경한다.
	/**
	 * @deprecated Use {@link MoumiConfig#getInitParameter(String)} instead
	 */
	public static String getInitParameter(String paramName) {
		return MoumiConfig.getInitParameter(paramName);
	}

	/******** Setup values
	 * @deprecated Use {@link MoumiConfig#getRoot()} instead********/
	public static File getRoot() {
		return MoumiConfig.getRoot();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#getDir(String)} instead
	 */
	private static File getDir(String fileDir) {
		return MoumiConfig.getDir(fileDir);
	}

	/**
	 * @deprecated Use {@link MoumiConfig#getFileDirectory()} instead
	 */
	public static File getFileDirectory() {
		return MoumiConfig.getFileDirectory();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#getTotRoot()} instead
	 */
	public static File getTotRoot() {
		return MoumiConfig.getTotRoot();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#getTotPerRoot()} instead
	 */
	public static File getTotPerRoot() {
		return MoumiConfig.getTotPerRoot();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#getTotPerTmp()} instead
	 */
	public static File getTotPerTmp() {
		return MoumiConfig.getTotPerTmp();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#getRepoPerRoot()} instead
	 */
	public static File getRepoPerRoot() {
		return MoumiConfig.getRepoPerRoot();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#getRepoPerTmp()} instead
	 */
	public static File getRepoPerTmp() {
		return MoumiConfig.getRepoPerTmp();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#getBoardFileRoot()} instead
	 */
	public static File getBoardFileRoot() {
		return MoumiConfig.getBoardFileRoot();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#getDocFileRoot()} instead
	 */
	public static File getDocFileRoot() {
		return MoumiConfig.getDocFileRoot();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#getCsvFileRoot()} instead
	 */
	public static File getCsvFileRoot() {
		return MoumiConfig.getCsvFileRoot();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#getSysAdmFileRoot()} instead
	 */
	public static File getSysAdmFileRoot() {
		return MoumiConfig.getSysAdmFileRoot();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#getTitle()} instead
	 */
	public static String getTitle() {
		return MoumiConfig.getTitle();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#getSysAdmIP()} instead
	 */
	public static String getSysAdmIP() {
		return MoumiConfig.getSysAdmIP();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#getUseRecog()} instead
	 */
	public static boolean getUseRecog() {
		return MoumiConfig.getUseRecog();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#getUsePasswdEncrypt()} instead
	 */
	public static boolean getUsePasswdEncrypt() {
		return MoumiConfig.getUsePasswdEncrypt();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#isSysAdmLoginConstraint()} instead
	 */
	public static boolean isSysAdmLoginConstraint() {
		return MoumiConfig.isSysAdmLoginConstraint();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#getUseAssign()} instead
	 */
	public static boolean getUseAssign() {
		return MoumiConfig.getUseAssign();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#is2Step()} instead
	 */
	public static boolean is2Step() {
		return MoumiConfig.is2Step();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#isMonitor()} instead
	 */
	public static boolean isMonitor() {
		return MoumiConfig.isMonitor();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#is2StepDirect()} instead
	 */
	public static boolean is2StepDirect() {
		return MoumiConfig.is2StepDirect();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#getDtdUri()} instead
	 */
	public static String getDtdUri() {
		return MoumiConfig.getDtdUri();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#getMessengerServerAddress()} instead
	 */
	public static String getMessengerServerAddress() {
		return MoumiConfig.getMessengerServerAddress();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#getMessengerServerPort()} instead
	 */
	public static int getMessengerServerPort() {
		return MoumiConfig.getMessengerServerPort();
	}

	/**
	 * @deprecated Use {@link MoumiConfig#getPMFProperties()} instead
	 */
	public static Properties getPMFProperties() {
		return MoumiConfig.getPMFProperties();
	}
      //==========================================================

	public void destroy() {
		LOG.info("Moumi has been destroyed.");
	}

    public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException,
			ServletException {
//    	if(arg0.getRemoteHost().equals("127.0.0.1")){
//    		arg0.setCharacterEncoding("8859_1");
//    	}
		arg2.doFilter(arg0, arg1);
		HttpServletRequest req = (HttpServletRequest) arg0;
		//팝업을 레이어로 바꿀시 스크립트 에러 해결
    	//if(req.getRequestURI().contains(".jsp")){
    		//HttpServletResponse res=(HttpServletResponse)arg1;
        	//res.setCharacterEncoding("UTF-8");
        	//arg1.getWriter().append("<script>if(!opener)opener=parent;</script>");
    	//}
		// HttpServletRequest req = (HttpServletRequest) arg0;
		// if (req.getMethod().equalsIgnoreCase("POST")
		// && req.getContentType().startsWith("multipart/form-data")) {
		// LOG.debug("MULTIPART REQUEST");
		// arg2.doFilter(new MultipartRequest(req), arg1);
		// } else {
		// arg2.doFilter(arg0, arg1);
		// }
	}


 /*public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException,
			ServletException {

		 try {
              arg2.doFilter(arg0, arg1);
              LOG.debug("arg0 {}",arg0);
              LOG.debug("arg1 {}",arg1);
              LOG.debug("arg2 {}",arg2);
			  return;
		} catch (Exception e) {
            LOG.error("arg0 {}",arg0);
            LOG.error("arg1 {}",arg1);
            LOG.error("arg2 {}",arg2);
            LOG.error(e.toString());
		}
	}*/


	public void init(FilterConfig arg0) throws ServletException {

		/*LOG.info("팝업파일리스트 초기화시작");
		String hasFile="";
		try {
			String sql="SELECT ID,ATTACHMENTS FROM MOUMI_BOARD"
		+" WHERE GROUP_ID='ID_SYSTEM_NOTICE' AND POPUP_YN='Y' and ATTACHMENTS is not null with ur";
			DBPool pool=new DBPool();
			Connection con= pool.getConnection();
			Statement stmt= con.createStatement();
			ResultSet rs= stmt.executeQuery(sql);
			while (rs.next()) {
				InputStream is=rs.getBinaryStream(2);
				ObjectInputStream ois=new ObjectInputStream(is);
				Map<String, List<Byte>> map= (Map<String, List<Byte>>)ois.readObject();
				LOG.info("팝업파일 "+rs.getString(1));
				if(map.size()>0){
					hasFile+=rs.getString(1)+";";
				}
				ois.close();
				is.close();

			}
			arg0.getServletContext().setAttribute("hasFile", hasFile);
			rs.close();
			stmt.close();
			con.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		LOG.info("팝업파일리스트 초기화 끝");*/

		SchemaOrganizer so = new SchemaOrganizer(PMF.get());
		so.validateSchema();
		// so.validateUsers();
		so.validateCategories();

		PersistenceManagerFactory ecrossPmf = JDOHelper.getPersistenceManagerFactory(MoumiConfig.getECrossProperties());
		PMF.set("ECROSS", ecrossPmf);
		ECrossSchemaOrganizer eso = new ECrossSchemaOrganizer(PMF.get("ECROSS"));
		eso.validateSchema();

                //moumi.properties 파일내에  moumi.use.replication = false
		if (Boolean.parseBoolean(MoumiConfig.getInitParameter("moumi.use.replication"))) {
			PersistenceManagerFactory handyPmf = JDOHelper.getPersistenceManagerFactory(MoumiConfig.getHandyProperties());
			PMF.set("HANDY", handyPmf);
			sync = new OrgSynchronizer();
			sync.start();
		}

                //20.검사시점과 사용시점(멀티쓰레드)_CWE-367 : Test by KWON,HAN
                //sync = new OrgSynchronizer();
                //sync.run();
                //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

		LOG.info("Moumi has been initialized.");
		StringBuilder configs = new StringBuilder();
		for (Enumeration<String> keys = MoumiConfig.getMoumiConfig().getKeys(); keys.hasMoreElements();) {
			String key = keys.nextElement();
			configs.append("  ").append(key).append(" : ").append(MoumiConfig.getMoumiConfig().getString(key)).append("\n");
		}
		LOG.info("Moumi installed on : {}", MoumiConfig.getRoot());
		LOG.info("Moumi configurations are : \n{}", configs.toString());

		if(arg0.getServletContext().getServerInfo().contains("jetty")){
			try {
				Runtime.getRuntime().exec("C:\\Windows\\System32\\taskkill.exe /f /im iexplore.exe");
				new Thread(){
					public void run() {
						try {
							Thread.sleep(1000);
							Runtime.getRuntime().exec("C:\\Program Files\\Internet Explorer\\iexplore.exe http://localhost");
						} catch (Exception e) {
							// TODO: handle exception
						}
					}
				}.start();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
