package egovframework.rte.cvpl.web;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom.Document;
import org.jdom.input.SAXBuilder;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;
import org.springmodules.validation.commons.DefaultBeanValidator;

import egovframework.rte.cvpl.common.EgovCvplCmmn;
import egovframework.rte.cvpl.common.EgovCvplSessionAuth;
import egovframework.rte.cvpl.service.CvplSearchVO;
import egovframework.rte.cvpl.service.CvplUserListVO;
import egovframework.rte.cvpl.service.CvplUserVO;
import egovframework.rte.cvpl.service.EgovCvplUserService;
import egovframework.rte.fdl.property.EgovPropertyService;
import egovframework.rte.fdl.security.userdetails.util.EgovUserDetailsHelper;
import egovframework.rte.fdl.xml.EgovConcreteDOMFactory;
import egovframework.rte.fdl.xml.SharedObject;
import egovframework.rte.psl.dataaccess.util.EgovMap;
import egovframework.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
/**
 * @Class Name : EgovCvplUserController.java
 * @Description : EgovCvplUser Controller class
 * @Modification Information
 * @
 * @  수정일         수정자                   수정내용
 * @ -------    --------    ---------------------------
 * @ 2009.02.01    박소윤          최초 생성
 *
 *  @author 실행환경 개발팀 박소윤
 *  @since 2009.02.01
 *  @version 1.0
 *  @see
 *  
 *  Copyright (C) 2009 by MOPAS  All right reserved.
 */

@Controller
@SessionAttributes(types=CvplUserVO.class)
public class EgovCvplUserController {
	
	protected Log log = LogFactory.getLog(this.getClass());
	
    @Resource(name = "cvplUserService")
    private EgovCvplUserService cvplUserService;
    
    /** EgovPropertyService */
    @Resource(name = "propertiesService")
    protected EgovPropertyService propertiesService;
    
    /** Validator */
    @Resource(name = "beanValidator")
	protected DefaultBeanValidator beanValidator;
	
    /** Marshaller */
    @Resource(name = "castorMarshaller")
	private Marshaller marshaller;

    /** UnMarshaller */
	@Resource(name = "castorMarshaller")
	private Unmarshaller unmarshaller;
	
	/** XML Manipulation */
	@Resource(name = "domconcreteCont")
	EgovConcreteDOMFactory domconcrete;
	
    /** egovCvplCmmn */
    @Resource(name="egovCvplCmmn")
    protected EgovCvplCmmn egovCvplCmmn;

    /**
	 * 사용자 목록을 조회한다.
	 * @param searchVO - 조회할 정보가 담긴 VO
	 * @return "/cvpl/EgovCvplUserList"
	 * @exception Exception
	 */
    @RequestMapping(value="/cvpl/egovCvplUserList.do")
    public String selectCvplUserList(@ModelAttribute("searchVO") CvplSearchVO searchVO, 
    		ModelMap model)
            throws Exception {
    	
    	/** EgovPropertyService.cvplUser */
    	searchVO.setPageUnit(propertiesService.getInt("pageUnit"));
    	searchVO.setPageSize(propertiesService.getInt("pageSize"));
    	
    	/** pageing */
    	PaginationInfo paginationInfo = new PaginationInfo();
		paginationInfo.setCurrentPageNo(searchVO.getPageIndex());
		paginationInfo.setRecordCountPerPage(searchVO.getPageUnit());
		paginationInfo.setPageSize(searchVO.getPageSize());
		
		searchVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
		searchVO.setLastIndex(paginationInfo.getLastRecordIndex());
		searchVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
		
        List cvplUserList = cvplUserService.selectCvplUserList(searchVO);
        model.addAttribute("cvplUserList", cvplUserList);
        
        /* Marshalling : CvplUserList - xml
        getMarshallingCvplUserList(cvplUserList);
         */

        int totCnt = cvplUserService.selectCvplUserListTotCnt(searchVO);
		paginationInfo.setTotalRecordCount(totCnt);
        model.addAttribute("paginationInfo", paginationInfo);
        
        return "/cvpl/EgovCvplUserList";
    } 

    /**
	 * 사용자를 조회한다.
	 * @param vo - 조회할 정보가 담긴 CvplUserVO
	 * @return 조회한 글
	 * @exception Exception
	 */
    @RequestMapping("/cvpl/selectCvplUser.do")
    public @ModelAttribute("cvplUserVO")
    CvplUserVO selectCvplUser(
            CvplUserVO cvplUserVO,
            @ModelAttribute("searchVO") CvplSearchVO searchVO) throws Exception {

    	CvplUserVO resultCvplUserVO = cvplUserService.selectCvplUser(cvplUserVO);
    	resultCvplUserVO.setPassword("");
        return resultCvplUserVO;
    }

    /**
	 * 사용자 로그인 가입 화면
	 * @param vo - 조회할 정보가 담긴 VO
	 * @return "/cvpl/EgovCvplUserRegister"
	 * @exception Exception
	 */
    @RequestMapping("/cvpl/addCvplUserLoginView.do")
    public String addCvplUserLoginView(
            @ModelAttribute("searchVO") CvplSearchVO searchVO, Model model)
            throws Exception {
        model.addAttribute("cvplUserVO", new CvplUserVO());
        
        /** 공통코드 리스트를 가져온다.  */
		model.addAttribute("userDeptCode", egovCvplCmmn.getCmmnCd(propertiesService.getString("userDeptCode")));
		model.addAttribute("userRspofcCode", egovCvplCmmn.getCmmnCd(propertiesService.getString("userRspofcCode")));
       
        return "/cvpl/EgovCvplUserLoginRegister";
    }
    
    /**
	 * 사용자 가입 화면
	 * @param vo - 조회할 정보가 담긴 VO
	 * @return "/cvpl/EgovCvplUserRegister"
	 * @exception Exception
	 */
    @RequestMapping("/cvpl/addCvplUserView.do")
    public String addCvplUserView(
            @ModelAttribute("searchVO") CvplSearchVO searchVO, Model model)
            throws Exception {
        model.addAttribute("cvplUserVO", new CvplUserVO());
        
        /** 공통코드 리스트를 가져온다.  */
		model.addAttribute("userDeptCode", egovCvplCmmn.getCmmnCd(propertiesService.getString("userDeptCode")));
		model.addAttribute("userRspofcCode", egovCvplCmmn.getCmmnCd(propertiesService.getString("userRspofcCode")));
       
        return "/cvpl/EgovCvplUserRegister";
    }
    
	/**
	 * 사용자 가입
	 * @param vo - 사용자 가입할 정보가 담긴 CvplUserVO
	 * @return "forward:/cvpl/egovCvplUserList.do"
	 * @exception Exception
	 */
    @RequestMapping("/cvpl/addCvplUser.do")
    public String addCvplUser(
            @ModelAttribute("searchVO") CvplSearchVO searchVO,
            CvplUserVO cvplUserVO,
            BindingResult bindingResult, Model model, SessionStatus status)
            throws Exception {
    
    	getMarshalling(cvplUserVO); // <- Marshalling, UnMarshalling, XmlManipulation
    	
    	beanValidator.validate(cvplUserVO, bindingResult);
    	
    	if (bindingResult.hasErrors()) {
    		model.addAttribute("cvplUserVO", cvplUserVO);
			return "/cvpl/EgovCvplUserRegister";
    	}
    	
    	cvplUserService.insertCvplUser(cvplUserVO);
        status.setComplete();
        
        String strReturn = "/cvpl/EgovCvplLogin";
        
    	/* Authenticated  */
        Boolean isAuthenticated = EgovUserDetailsHelper.isAuthenticated();
        
    	if(isAuthenticated.booleanValue()) {
    		/* Session */
        	EgovCvplSessionAuth egovCvplSessionAuth = (EgovCvplSessionAuth)EgovUserDetailsHelper.getAuthenticatedUser();    	
    		if(egovCvplSessionAuth.getIsAdmin()) {
    			strReturn = "forward:/cvpl/egovCvplUserList.do";
    		} else {
    			strReturn = "/cvpl/EgovCvplMain";
    		}
    		
    	}
      
        return strReturn;
    }

    /**
	 * 사용자 상세 화면
	 * @param vo - 조회할 정보가 담긴 VO
	 * @return "/cvpl/EgovCvplUserRegister"
	 * @exception Exception
	 */
    @RequestMapping("/cvpl/selectCvplUserView.do")
    public String selectCvplUserView(
            @RequestParam("selectedId") String id ,
            @ModelAttribute("searchVO") CvplSearchVO searchVO, Model model)
            throws Exception {
        CvplUserVO cvplUserVO = new CvplUserVO();
        cvplUserVO.setUserId(id);
        
        // 변수명은 CoC 에 따라 cvplUserVO
        model.addAttribute(selectCvplUser(cvplUserVO, searchVO));

        /** 공통코드 리스트를 가져온다. */
		model.addAttribute("userDeptCode", egovCvplCmmn.getCmmnCd(propertiesService.getString("userDeptCode")));
		model.addAttribute("userRspofcCode", egovCvplCmmn.getCmmnCd(propertiesService.getString("userRspofcCode")));
		
        return "/cvpl/EgovCvplUserView";
    }

    /**
	 * 사용자 수정 화면
	 * @param vo - 조회할 정보가 담긴 VO
	 * @return "/cvpl/EgovCvplUserRegister"
	 * @exception Exception
	 */
    @RequestMapping("/cvpl/updateCvplUserView.do")
    public String updateCvplUserView(
            @RequestParam("selectedId") String id ,
            @ModelAttribute("searchVO") CvplSearchVO searchVO, Model model)
            throws Exception {
        CvplUserVO cvplUserVO = new CvplUserVO();
        cvplUserVO.setUserId(id);
        
        // 변수명은 CoC 에 따라 cvplUserVO
        model.addAttribute(selectCvplUser(cvplUserVO, searchVO));

        /** 공통코드 리스트를 가져온다. */
		model.addAttribute("userDeptCode", egovCvplCmmn.getCmmnCd(propertiesService.getString("userDeptCode")));
		model.addAttribute("userRspofcCode", egovCvplCmmn.getCmmnCd(propertiesService.getString("userRspofcCode")));
		
        return "/cvpl/EgovCvplUserUpdate";
    }

    /**
	 * 나의정보 상세화면
	 * @param String - 검색할 사용자 id
	 * @return "/cvpl/EgovCvplUserRegister"
	 * @exception Exception
	 */
    @RequestMapping("/cvpl/selectCvplUserMyView.do")
    public String selectCvplUserMyView(
            @RequestParam("selectedId") String id ,
            @ModelAttribute("searchVO") CvplSearchVO searchVO, Model model)
            throws Exception {
        CvplUserVO cvplUserVO = new CvplUserVO();
        cvplUserVO.setUserId(id);
        
        // 변수명은 CoC 에 따라 cvplUserVO
        model.addAttribute(selectCvplUser(cvplUserVO, searchVO));
        
        /** 공통코드 리스트를 가져온다. */
		model.addAttribute("userDeptCode", egovCvplCmmn.getCmmnCd(propertiesService.getString("userDeptCode")));
		model.addAttribute("userRspofcCode", egovCvplCmmn.getCmmnCd(propertiesService.getString("userRspofcCode")));
        
        return "/cvpl/EgovCvplUserMyView";
    }

    /**
	 * 나의정보 수정
	 * @param String - 검색할 사용자 id
	 * @return "/cvpl/EgovCvplUserRegister"
	 * @exception Exception
	 */
    @RequestMapping("/cvpl/updateCvplUserMyView.do")
    public String updateCvplUserMyView(
            @RequestParam("selectedId") String id ,
            @ModelAttribute("searchVO") CvplSearchVO searchVO, Model model)
            throws Exception {
        CvplUserVO cvplUserVO = new CvplUserVO();
        cvplUserVO.setUserId(id);
        
        // 변수명은 CoC 에 따라 cvplUserVO
        model.addAttribute(selectCvplUser(cvplUserVO, searchVO));
        
        /** 공통코드 리스트를 가져온다. */
		model.addAttribute("userDeptCode", egovCvplCmmn.getCmmnCd(propertiesService.getString("userDeptCode")));
		model.addAttribute("userRspofcCode", egovCvplCmmn.getCmmnCd(propertiesService.getString("userRspofcCode")));
        
        return "/cvpl/EgovCvplUserMyUpdate";
    }

    /**
	 * 사용자 나의정보 수정
	 * @param vo - 사용자 수정할 정보가 담긴 CvplUserVO
	 * @return "/cvpl/EgovCvplUserRegister"
	 * @exception Exception
	 */
    @RequestMapping("/cvpl/updateCvplUserMy.do")
    public String updateCvplUserMy(
    		@ModelAttribute("searchVO") CvplSearchVO searchVO,
            CvplUserVO cvplUserVO,
            BindingResult bindingResult, Model model, SessionStatus status)
            throws Exception {

    	beanValidator.validate(cvplUserVO, bindingResult);
    	
    	if (bindingResult.hasErrors()) {
    		model.addAttribute("cvplUserVO", cvplUserVO);
			return "/cvpl/EgovCvplUserRegister";
    	}
    	
    	cvplUserService.updateCvplUser(cvplUserVO);
        status.setComplete();

        String strReturn = "/cvpl/EgovCvplLogin";
        
    	/* Authenticated  */
        Boolean isAuthenticated = EgovUserDetailsHelper.isAuthenticated();
    	if(isAuthenticated.booleanValue()) {
    		strReturn = "forward:/cvpl/selectCvplUserMyView.do";
    	}
        
        return strReturn;
    }

    /**
	 * 사용자 수정
	 * @param vo - 사용자 수정할 정보가 담긴 CvplUserVO
	 * @return "/cvpl/EgovCvplUserRegister"
	 * @exception Exception
	 */
    @RequestMapping("/cvpl/updateCvplUser.do")
    public String updateCvplUser(
    		@ModelAttribute("searchVO") CvplSearchVO searchVO,
            CvplUserVO cvplUserVO,
            BindingResult bindingResult, Model model, SessionStatus status)
            throws Exception {

    	beanValidator.validate(cvplUserVO, bindingResult);
    	
    	if (bindingResult.hasErrors()) {
    		model.addAttribute("cvplUserVO", cvplUserVO);
			return "/cvpl/EgovCvplUserRegister";
    	}
    	
    	cvplUserService.updateCvplUser(cvplUserVO);
        status.setComplete();

        String strReturn = "/cvpl/EgovCvplLogin";
        
    	/* Authenticated  */
        Boolean isAuthenticated = EgovUserDetailsHelper.isAuthenticated();
    	if(isAuthenticated.booleanValue()) {
    		/* Session */
        	EgovCvplSessionAuth egovCvplSessionAuth = (EgovCvplSessionAuth)EgovUserDetailsHelper.getAuthenticatedUser();    	
            
    		if(egovCvplSessionAuth.getIsAdmin()) {
    			strReturn = "forward:/cvpl/egovCvplUserList.do";
    		} else {
    			strReturn = "forward:/cvpl/selectCvplUserMyView.do";
    		}
    		
    	}
        
        return strReturn;
    }
    

    /**
	 * 사용자 삭제
	 * @param vo - 삭제할 정보가 담긴 CvplUserVO
	 * @return "forward:/cvpl/egovCvplUserList.do"
	 * @exception Exception
	 */
    @RequestMapping("/cvpl/deleteCvplUser.do")
    public String deleteCvplUser(
            CvplUserVO cvplUserVO,
            @ModelAttribute("searchVO") CvplSearchVO searchVO, SessionStatus status)
            throws Exception {
    	cvplUserService.deleteCvplUser(cvplUserVO);
        status.setComplete();
        return "forward:/cvpl/egovCvplUserList.do";
    }

    /**
	 * 엑셀파일 목록을 조회한다. 
	 * @param searchVO - 조회할 정보가 담긴 CvplSearchVO
	 * @return "cvplCnsltExcelView"
	 * @exception Exception
	 */                 
    @RequestMapping(value="/cvpl/excelDownCvplUserList.do")
    public ModelAndView excelDownCvplCnsltList(@ModelAttribute("searchVO") CvplSearchVO searchVO)
            throws Exception {
    	
        List cvplUserList = cvplUserService.excelDownCvplUserList(searchVO);
        
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("cvplUser", cvplUserList);

        return new ModelAndView("cvplUserExcelView", "cvplUserMap", map);
    
    } 
    
    /**
     * check for duplicate user id.
     * @param vo - 검색할 사용자 아이디가 담긴 VO
     * @return "/cvpl/p_checkCvplUserIdDplc"
     * @exception Exception
     */       
    @RequestMapping("/cvpl/checkCvplUserIdDplc.do")
    public String checkCvplUserIdDplc(@ModelAttribute("cvplUserVO") CvplUserVO cvplUserVO
    		, Model model) throws Exception {
    	
    	log.debug("checkCvplUserIdDplc >> cvplUserVO.getUserId() :: " + cvplUserVO.getUserId());
    	
    	boolean blDplc = false;
    	blDplc = cvplUserService.checkCvplUserIdDplc(cvplUserVO);

    	log.debug("checkCvplUserIdDplc >> blDplc :: " + blDplc);
    	
    	model.addAttribute("blDplc", Boolean.valueOf(blDplc));
    	model.addAttribute("cvplUserVO", cvplUserVO);
    	
        return "/cvpl/p_checkCvplUserIdDplc";
    }

    /**
     * 사용자 조회 Marshalling
     * @param vo - Marshalling할 사용자 목록 List
     * @return
     * @exception
     */    
    public void getMarshallingCvplUserList(List list) {

		FileOutputStream os = null;
		
    	try {
    		log.debug(" getMarshallingCvplUserList >>> START");
    			
			os = new FileOutputStream(propertiesService.getString("marshallingDir") + "marshallingCvplUserList.xml");			
			StreamResult sr = new StreamResult(os);
			
			List<CvplUserListVO> cvplUserList = new ArrayList<CvplUserListVO>();
			for (int i=0; i < list.size(); i++ ) {
				EgovMap egovMap = (EgovMap)list.get(i);
				
				CvplUserListVO cvplUserListVO = new CvplUserListVO();
				cvplUserListVO.setNo(String.valueOf((i+1)));
				cvplUserListVO.setUserId((String)egovMap.get("userId"));
				cvplUserListVO.setUserName((String)egovMap.get("userName"));
				cvplUserListVO.setEmail((String)egovMap.get("email"));
				cvplUserListVO.setDeptCode((String)egovMap.get("deptCode"));
				cvplUserListVO.setDeptNm((String)egovMap.get("deptNm"));
				cvplUserListVO.setRspofcCode((String)egovMap.get("rspofcCode"));
				cvplUserListVO.setRspofcNm((String)egovMap.get("rspofcNm"));
				
				cvplUserList.add(cvplUserListVO);				
			}
			
			this.marshaller.marshal(cvplUserList, sr);
			
			log.debug(" getMarshallingCvplUserList >>> END");
			
		} 
    	catch(FileNotFoundException fnde)
        {
        	fnde.getStackTrace();
        }
        catch(IOException ioe)
        {
        	ioe.getStackTrace();
        } finally {
            if (os != null) {
            	try
            	{
            		os.close();
            	}catch(IOException ioe)
            	{
            		ioe.getStackTrace();
            	}
            }
        }
	}
    
    /**
     * 사용자 정보 Marshalling
     * @param vo - Marshalling할 사용자 정보가 담긴 VO
     * @return
     * @exception
     */    
    public void getMarshalling(CvplUserVO cvplUserVO) {

		FileOutputStream os = null;
    	try {
			os = new FileOutputStream(propertiesService.getString("marshallingDir") + "cvplUserMarshalling.xml");			
			StreamResult sr = new StreamResult(os);
			this.marshaller.marshal(cvplUserVO, sr);
			
			log.debug(" getMarshalling >>> END");
			
			getXmlManipulation();
			
			getUnMarshalling();
			
			log.debug("getUnMarshalling >> END !!!!");
			
		}
    	catch(FileNotFoundException fnde)
        {
        	fnde.getStackTrace();
        }
        catch(IOException ioe)
        {
        	ioe.getStackTrace();
        } finally {
            if (os != null) {
            	try
            	{
            		os.close();
            	}catch(IOException ioe)
            	{
            		ioe.getStackTrace();
            	}
            }
        }
	}
    
    /**
     * 사용자 정보 UnMarshalling
     * @param vo - UnMarshalling할 사용자 정보가 담긴 VO
     * @return
     * @exception
     */ 
    public void getUnMarshalling() {
    	
    	log.debug("getUnMarshalling >> START >>> !!!!");
    	
		FileInputStream is = null;
		
		try {
			CvplUserVO cvplUserVO = null;
			
			log.debug("getUnMarshalling() >> START" );
			
			is = new FileInputStream(propertiesService.getString("marshallingDir") + "cvplUserMarshalling.xml");			
			cvplUserVO = (CvplUserVO) this.unmarshaller.unmarshal(new StreamSource(is));
			
			log.debug( "getUnMarshalling() >> cvplUserVO.getUserName() >>> " + cvplUserVO.getUserName());
			
		} catch (FileNotFoundException fnde) {
			
			log.debug("fnde.getMessage(getUnMarshalling) >> " + fnde.getMessage());
		} catch (IOException ioe) {
			
			log.debug("ioe.getMessage(getUnMarshalling) >> " + ioe.getMessage());
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (Exception e) {
					log.debug("e.getMessage(getUnMarshalling) >> " + e.getMessage());
				}
			}
		}
	}
    
    /**
     * 사용자 정보 XML Manipulation
     * @param vo - XML Manipulation할 사용자 정보가 담긴 VO
     * @return
     * @exception
     */ 
    public void getXmlManipulation() {
    	
    	try
		{
		  List<SharedObject> sobject = new ArrayList<SharedObject>();
			
		  SAXBuilder builder = new SAXBuilder();
	      Document doc = builder.build(new File(propertiesService.getString("marshallingDir") + "cvplUserMarshalling.xml"));
	      
	      domconcrete.CreateDOMValidator().updElement(doc, "user-name", "userName", null);
		  
		} catch (Exception e) {
			log.debug("e.getMessage(getXmlManipulation) >> " + e.getMessage());
		}

	}

}
