package itn.let.sec.rmt.web;

import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
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.support.SessionStatus;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.support.RequestContextUtils;
import org.springmodules.validation.commons.DefaultBeanValidator;

import egovframework.rte.fdl.idgnr.EgovIdGnrService;
import egovframework.rte.fdl.property.EgovPropertyService;
import egovframework.rte.fdl.security.userdetails.util.EgovUserDetailsHelper;
import egovframework.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
import itn.com.cmm.ComDefaultCodeVO;
import itn.com.cmm.EgovMessageSource;
import itn.com.cmm.LoginVO;
import itn.com.cmm.service.EgovCmmUseService;
import itn.com.cmm.util.EgovDoubleSubmitHelper;
import itn.com.cmm.util.RedirectUrlMaker;
import itn.let.sec.ram.service.AuthorManageVO;
import itn.let.sec.ram.service.EgovAuthorManageService;
import itn.let.sec.rmt.service.EgovRoleManageService;
import itn.let.sec.rmt.service.RoleManage;
import itn.let.sec.rmt.service.RoleManageVO;
import itn.let.uss.umt.service.UserDefaultVO;

/**
 * 롤관리에 관한 controller 클래스를 정의한다.
 * @author 공통서비스 개발팀 이문준
 * @since 2009.06.01
 * @version 1.0
 * @see
 *
 * <pre>
 * << 개정이력(Modification Information) >>
 *
 *   수정일      수정자           수정내용
 *  -------    --------    ---------------------------
 *   2009.03.11  이문준          최초 생성
 *   2011.08.31  JJY            경량환경 템플릿 커스터마이징버전 생성
 *
 * </pre>
 */

@Controller
public class EgovRoleManageController {

    @Resource(name="egovMessageSource")
    EgovMessageSource egovMessageSource;

    @Resource(name = "egovRoleManageService")
    private EgovRoleManageService egovRoleManageService;

    @Resource(name = "EgovCmmUseService")
    EgovCmmUseService egovCmmUseService;

    @Resource(name = "egovAuthorManageService")
    private EgovAuthorManageService egovAuthorManageService;

    /** EgovPropertyService */
    @Resource(name = "propertiesService")
    protected EgovPropertyService propertiesService;

    /** Message ID Generation */
    @Resource(name="egovRoleIdGnrService")
    private EgovIdGnrService egovRoleIdGnrService;

    @Autowired
	private DefaultBeanValidator beanValidator;

  //배열 정의{"컬럼순차번호, 컬럼이름, 컬럼내용, 컬럼이름에 붙여야할 내용(엑셀코드양식다운로드시 필요)"}
  	private String[][] roleExcelValue ={
  	    {"0", "번호" , "1" , "" },
  	    {"1", "롤ID" , "WEB_ROLE" , ""}, 
  	    {"2", "롤명" , "itn-cop-bbs", ""},
  	    {"3", "롤패턴" , "/itn/web/cop/bbs/.*.do.*", ""},
  	    {"4", "롤타입" , "URL", ""}, 
  	    {"5", "롤순서" , "1", "(숫자)"}, 
  	    {"6", "롤설명" , "게시판", ""}, 
  	    {"7", "등록일자" , "2019-06-17", "(날짜형식)"} 
  	} ;
    /**
	 * 롤 목록화면 이동
	 * @return String
	 * @exception Exception
	 */
    @RequestMapping("/sec/rmt/EgovRoleListView.do")
    public String selectRoleListView()
            throws Exception {
        return "/sec/rmt/EgovRoleManage";
    }

	/**
	 * 등록된 롤 정보 목록 조회
	 * @param roleManageVO RoleManageVO
	 * @return String
	 * @exception Exception
	 */
    @RequestMapping(value="/sec/rmt/EgovRoleList.do")
	public String selectRoleList(@ModelAttribute("roleManageVO") RoleManageVO roleManageVO,
			HttpServletRequest request,
			ModelMap model) throws Exception {
    	if(roleManageVO.getPageUnit() != 10) {
    		roleManageVO.setPageUnit(roleManageVO.getPageUnit());
    	}
    	
    	Map<String, ?> flashMap =RequestContextUtils.getInputFlashMap(request);
    	
    	if(flashMap!=null && flashMap.get("roleManageVO") != null) {
    		roleManageVO = (RoleManageVO)flashMap.get("roleManageVO");
    		model.addAttribute("roleManageVO", roleManageVO);
        }
    	
    	/** paging */
     	PaginationInfo paginationInfo = new PaginationInfo();
		paginationInfo.setCurrentPageNo(roleManageVO.getPageIndex());
		paginationInfo.setRecordCountPerPage(roleManageVO.getPageUnit());
		paginationInfo.setPageSize(roleManageVO.getPageSize());

		roleManageVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
		roleManageVO.setLastIndex(paginationInfo.getLastRecordIndex());
		roleManageVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());

		if("".equals(roleManageVO.getSearchSortCnd())){ //최초조회시 최신것 조회List
			roleManageVO.setSearchSortCnd("SORT_TEMP_NO");
			roleManageVO.setSearchSortOrd("desc");
		}else {
			if("ROLE_SORT".equals(roleManageVO.getSearchSortCnd())) {
				roleManageVO.setSearchSortCnd("CAST(ROLE_SORT AS UNSIGNED)");  //string to int cast
			}
		}
		roleManageVO.setRoleManageList(egovRoleManageService.selectRoleList(roleManageVO));
		if("CAST(ROLE_SORT AS UNSIGNED)".equals(roleManageVO.getSearchSortCnd())) {
			roleManageVO.setSearchSortCnd("ROLE_SORT");  //string to int cast
		}
        model.addAttribute("roleList", roleManageVO.getRoleManageList());
        int totCnt = egovRoleManageService.selectRoleListTotCnt(roleManageVO);
		paginationInfo.setTotalRecordCount(totCnt);
        model.addAttribute("paginationInfo", paginationInfo);
        return "/sec/rmt/EgovRoleManage";
	}

	/**
	 * 등록된 롤 정보 조회
	 * @param roleCode String
	 * @param roleManageVO RoleManageVO
	 * @param authorManageVO AuthorManageVO
	 * @return String
	 * @exception Exception
	 */
    @RequestMapping(value="/sec/rmt/EgovRole.do")
	public String selectRole(@RequestParam("roleCode") String roleCode,
	                         @ModelAttribute("roleManageVO") RoleManageVO roleManageVO,
	                         @ModelAttribute("authorManageVO") AuthorManageVO authorManageVO,
		                      ModelMap model) throws Exception {

    	roleManageVO.setRoleCode(roleCode);

    	authorManageVO.setAuthorManageList(egovAuthorManageService.selectAuthorAllList(authorManageVO));

    	model.addAttribute("roleManage", egovRoleManageService.selectRole(roleManageVO));
        model.addAttribute("authorManageList", authorManageVO.getAuthorManageList());
        model.addAttribute("cmmCodeDetailList", getCmmCodeDetailList(new ComDefaultCodeVO(),"COM029"));

        return "/sec/rmt/EgovRoleUpdate";
	}

    /**
	 * 롤 등록화면 이동
	 * @param authorManageVO AuthorManageVO
	 * @return String
	 * @exception Exception
	 */
    @RequestMapping("/sec/rmt/EgovRoleInsertView.do")
    public String insertRoleView(@ModelAttribute("authorManageVO") AuthorManageVO authorManageVO,
    		                      ModelMap model) throws Exception {

    	authorManageVO.setAuthorManageList(egovAuthorManageService.selectAuthorAllList(authorManageVO));
        model.addAttribute("authorManageList", authorManageVO.getAuthorManageList());
        model.addAttribute("cmmCodeDetailList", getCmmCodeDetailList(new ComDefaultCodeVO(),"COM029"));

        return "/sec/rmt/EgovRoleInsert";
    }

    /**
	 * 공통코드 호출
	 * @param comDefaultCodeVO ComDefaultCodeVO
	 * @param codeId String
	 * @return List
	 * @exception Exception
	 */
	public List<?> getCmmCodeDetailList(ComDefaultCodeVO comDefaultCodeVO, String codeId)  throws Exception {
    	comDefaultCodeVO.setCodeId(codeId);
    	return egovCmmUseService.selectCmmCodeDetail(comDefaultCodeVO);
    }

	/**
	 * 시스템 메뉴에 따른 접근권한, 데이터 입력, 수정, 삭제의 권한 롤을 등록
	 * @param roleManage RoleManage
	 * @param roleManageVO RoleManageVO
	 * @return String
	 * @exception Exception
	 */
    @RequestMapping(value="/sec/rmt/EgovRoleInsert.do")
	public String insertRole(@ModelAttribute("roleManage") RoleManage roleManage,
			                 @ModelAttribute("roleManageVO") RoleManageVO roleManageVO,
			                  BindingResult bindingResult,
			                  SessionStatus status,
			                  RedirectAttributes redirectAttributes,
                              ModelMap model) throws Exception {

    	beanValidator.validate(roleManage, bindingResult); //validation 수행
    	if (!EgovDoubleSubmitHelper.checkAndSaveToken("someKey")) {  
			return "forward:/sec/rmt/EgovRoleList.do";
		}	
    	
    	if (bindingResult.hasErrors()) {
			return "/sec/rmt/EgovRoleInsert";
		} else {
    	    String roleTyp = roleManage.getRoleTyp();
	    	if(roleTyp.equals("method"))
	    		roleTyp = "mtd";
	    	else if(roleTyp.equals("pointcut"))
	    		roleTyp = "pct";
	    	else roleTyp = "web";

	    	roleManage.setRoleCode(roleTyp.concat("-").concat(egovRoleIdGnrService.getNextStringId()));
	    	roleManageVO.setRoleCode(roleManage.getRoleCode());

	    	status.setComplete();
	        model.addAttribute("cmmCodeDetailList", getCmmCodeDetailList(new ComDefaultCodeVO(),"COM029"));
	    	model.addAttribute("message", egovMessageSource.getMessage("success.common.insert"));
	        model.addAttribute("roleManage", egovRoleManageService.insertRole(roleManage, roleManageVO));
	        
			redirectAttributes.addFlashAttribute("message", egovMessageSource.getMessage("success.common.insert"));
			RedirectUrlMaker redirectUrlMaker = new RedirectUrlMaker("/sec/rmt/EgovRoleList.do");
			return redirectUrlMaker.getRedirectUrl();
	        //return "/sec/rmt/EgovRoleUpdate";
		}
	}

	/**
	 * 시스템 메뉴에 따른 접근권한, 데이터 입력, 수정, 삭제의 권한 롤을 수정
	 * @param roleManage RoleManage
	 * @param bindingResult BindingResult
	 * @return String
	 * @exception Exception
	 */
    @RequestMapping(value="/sec/rmt/EgovRoleUpdate.do")
	public String updateRole(@ModelAttribute("roleManageVO") RoleManageVO roleManageVO,
			BindingResult bindingResult,
			SessionStatus status,
			RedirectAttributes redirectAttributes,
            ModelMap model) throws Exception {

    	if (!EgovDoubleSubmitHelper.checkAndSaveToken("someKey")) {  
			return "redirect:/sec/rmt/EgovRoleList.do";
		}	
    	
    	beanValidator.validate(roleManageVO, bindingResult); //validation 수행
    	if (bindingResult.hasErrors()) {
			return "/sec/rmt/EgovRoleUpdate";
		} else {
    	egovRoleManageService.updateRole(roleManageVO);
    	status.setComplete();
    	
    	redirectAttributes.addFlashAttribute("roleManageVO", roleManageVO);
    	
		redirectAttributes.addFlashAttribute("message", egovMessageSource.getMessage("success.common.update"));
		RedirectUrlMaker redirectUrlMaker = new RedirectUrlMaker("/sec/rmt/EgovRoleList.do");
		return redirectUrlMaker.getRedirectUrl();
		}
	}

	/**
	 * 불필요한 롤정보를 화면에 조회하여 데이터베이스에서 삭제
	 * @param roleManage RoleManage
	 * @return String
	 * @exception Exception
	 */
    @RequestMapping(value="/sec/rmt/EgovRoleDelete.do")
	public String deleteRole(@ModelAttribute("roleManageVO") RoleManageVO roleManageVO,
            SessionStatus status,
            RedirectAttributes redirectAttributes,
            ModelMap model) throws Exception {

    	egovRoleManageService.deleteRole(roleManageVO);
    	status.setComplete();
    	//model.addAttribute("message", egovMessageSource.getMessage("success.common.delete"));
    	redirectAttributes.addFlashAttribute("roleManageVO", roleManageVO);
    	
		redirectAttributes.addFlashAttribute("message", egovMessageSource.getMessage("success.common.delete"));
		RedirectUrlMaker redirectUrlMaker = new RedirectUrlMaker("/sec/rmt/EgovRoleList.do");
		return redirectUrlMaker.getRedirectUrl();
    	//return "forward:/sec/rmt/EgovRoleList.do";

	}

	/**
	 * 불필요한 그룹정보 목록을 화면에 조회하여 데이터베이스에서 삭제
	 * @param roleCodes String
	 * @param roleManage RoleManage
	 * @return String
	 * @exception Exception
	 */
	@RequestMapping(value="/sec/rmt/EgovRoleListDelete.do")
	public String deleteRoleList(@RequestParam("roleCodes") String roleCodes,
			                     @ModelAttribute("roleManage") RoleManage roleManage,
	                              SessionStatus status,
	                              RedirectAttributes redirectAttributes,
	                              Model model) throws Exception {
    	String [] strRoleCodes = roleCodes.split(";");
    	for(int i=0; i<strRoleCodes.length;i++) {
    		roleManage.setRoleCode(strRoleCodes[i]);
    		egovRoleManageService.deleteRole(roleManage);
    	}
		status.setComplete();
		redirectAttributes.addFlashAttribute("message", egovMessageSource.getMessage("success.common.delete"));
		RedirectUrlMaker redirectUrlMaker = new RedirectUrlMaker("/sec/rmt/EgovRoleList.do");
		return redirectUrlMaker.getRedirectUrl();
	}
	
	//리스트 엑셀 다운로드
  	@RequestMapping(value="/sec/rmt/roleListExcelDownload.do")
  	public void roleListExcelDownload(RoleManageVO roleManageVO, 
  			HttpServletRequest request, 
  			HttpServletResponse response , 
  			ModelMap model) throws Exception {
  		
  		roleManageVO.setRecordCountPerPage(100000);
  		roleManageVO.setFirstIndex(0);
  		LoginVO loginVO = (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser();
		if(null != loginVO && !"super".equals(loginVO.getSiteId())){
			roleManageVO.setSiteId(loginVO.getSiteId());
		}
		
  		// 메모리에 100개의 행을 유지합니다. 행의 수가 넘으면 디스크에 적습니다.
  		SXSSFWorkbook wb = new SXSSFWorkbook(100);
  		CellStyle style = wb.createCellStyle();
  		style.setBorderBottom(CellStyle.BORDER_THIN); //테두리 두껍게 
   		style.setBorderLeft(CellStyle.BORDER_THIN);
   		style.setBorderRight(CellStyle.BORDER_THIN);
   		style.setBorderTop(CellStyle.BORDER_THIN);
   		Font font = wb.createFont();
   		font.setBoldweight(Font.BOLDWEIGHT_BOLD);  //글씨 bold
   		
  		Cell cell = null;
  		Row row = null;
  		
  		String fileName ="롤 리스트";
  		String sheetTitle = "";
  		try{
  			List<RoleManageVO> roleManageList = egovRoleManageService.selectRoleList(roleManageVO) ;
  			{ //화면 리스트
  				sheetTitle = "롤 리스트(화면)" ; //제목
  				Sheet sheet = wb.createSheet(sheetTitle);
  				row = sheet.createRow(0);
  		        for(int i=0 ; i < roleExcelValue.length ; i++) {
  	 		       cell = row.createCell(i);
  	 		       cell.setCellStyle(style);
  		 	       cell.setCellValue(roleExcelValue[i][1]);
  	 		    }
  			        
  		        for(int i=0; i < roleManageList.size(); i++){
  			    	row = sheet.createRow(i+1);
  			    	for(int j=0 ; j < roleExcelValue.length ; j++) {
  			        	cell = row.createCell(j);
  			        	cell.setCellStyle(style);
  			        	if(j==0) cell.setCellValue(i+1); //번호
  			        	if(j==1) cell.setCellValue(roleManageList.get(i).getRoleCode()); //롤ID
  			        	if(j==2) cell.setCellValue(roleManageList.get(i).getRoleNm()); //롤명
  			        	if(j==3) cell.setCellValue(roleManageList.get(i).getRolePtn()); //롤패턴
  			        	if(j==4) cell.setCellValue(roleManageList.get(i).getRoleTyp()); //롤타입
  			        	if(j==5) cell.setCellValue(roleManageList.get(i).getRoleSort()); //롤순서
  			        	if(j==6) cell.setCellValue(roleManageList.get(i).getRoleDc()); //롤설명
  			        	if(j==7) cell.setCellValue(roleManageList.get(i).getRoleCreatDe()); //등록일자
  				 	}
  		        }
  			}
  			{ //DB리스트
  				sheetTitle = "롤 리스트(DB)" ; //제목
  				Sheet sheet = wb.createSheet(sheetTitle);
  				row = sheet.createRow(0);
  				for(int i=0 ; i < roleExcelValue.length-2 ; i++){ //아이디,등록일자 없어 -2
  					cell = row.createCell(i);
  	 		       	cell.setCellStyle(style);
  	 		       	if(i==0) {
  	 		       		cell.setCellValue("롤ID"); 
  	 		       	}else{ //2번제 컬럼 부터 하나씩 앞으로 세팅
	  	 		       	if(!"".equals(roleExcelValue[i+1][3])){
		 		       			cell.setCellValue(roleExcelValue[i+1][1]+"\n"+roleExcelValue[i+1][3]); 
	  		 	    	}else {
	  		 	    		cell.setCellValue(roleExcelValue[i+1][1]);
	  		 	    	}
  	 		       	}
  	 		    }
  			        
  		        for(int i=0; i < roleManageList.size(); i++){
  			    	row = sheet.createRow(i+1);
  			    	for(int j=0 ; j < roleExcelValue.length-2 ; j++) {//아이디 없어 -1
  			        	cell = row.createCell(j);
  			        	cell.setCellStyle(style);
  			        	if(j==0) cell.setCellValue(roleManageList.get(i).getRoleCode()); //롤ID
  			        	if(j==1) cell.setCellValue(roleManageList.get(i).getRoleNm()); //롤명
  			        	if(j==2) cell.setCellValue(roleManageList.get(i).getRolePtn()); //롤패턴
  			        	if(j==3) cell.setCellValue(roleManageList.get(i).getRoleTyp()); //롤타입
  			        	if(j==4) cell.setCellValue(roleManageList.get(i).getRoleSort()); //롤순서
  			        	if(j==5) cell.setCellValue(roleManageList.get(i).getRoleDc()); //롤설명
  			        	//if(j==6) cell.setCellValue(roleManageList.get(i).getRoleCreatDe()); //등록일자
 			 		}
  		        }	
  					
  			}
  	    response.setHeader("Set-Cookie", "fileDownload=true; path=/");
  		SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat ( "yyyy_MM_dd_HH_mm_ss", Locale.KOREA );
  		Date currentTime = new Date ();
  		String mTime = mSimpleDateFormat.format ( currentTime );
  		fileName = fileName+"("+mTime+")";
  		
  		response.setHeader("Content-Disposition", String.format("attachment; filename=\""+new String((fileName).getBytes("KSC5601"),"8859_1")+".xlsx"));
  		wb.write(response.getOutputStream());
  	    
  		}catch(Exception e) {
  			response.setHeader("Set-Cookie", "fileDownload=false; path=/");
  			response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
  			response.setHeader("Content-Type","text/html; charset=utf-8");
  			OutputStream out = null;
  			try {
  				out = response.getOutputStream();
  				byte[] data = new String("fail..").getBytes();
  				out.write(data, 0, data.length);
  			} catch(Exception ignore) {
  				ignore.printStackTrace();
  			} finally {
  				if(out != null) try { out.close(); } catch(Exception ignore) {}
  			}
  		}finally {
  			// 디스크 적었던 임시파일을 제거합니다.
  			wb.dispose();
  			try { wb.close(); } catch(Exception ignore) {}
  		}
  		
  	}

}