package com.eactive.eai.rms.common.board;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.helpers.LogLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import com.eactive.eai.common.util.UUID;
import com.eactive.eai.rms.common.acl.menu.MenuManService;
import com.eactive.eai.rms.common.base.BaseAnnotationController;
import com.eactive.eai.rms.common.context.MonitoringContext;
import com.eactive.eai.rms.common.datasource.DataSourceContextHolder;
import com.eactive.eai.rms.common.datasource.DataSourceTypeManager;
import com.eactive.eai.rms.common.login.SessionManager;
import com.eactive.eai.rms.common.util.CamelCaseUtil;
import com.eactive.eai.rms.common.util.StringUtils;
import com.eactive.eai.rms.common.vo.JsonPageVo;


@Controller
public class BoardController extends BaseAnnotationController  {

	@Autowired
	@Qualifier("boardService")
	private BoardService service; 

	@Autowired
	@Qualifier("menuManService")
	private MenuManService menuManService; 

	@Autowired
    @Qualifier("monitoringContext")
    private MonitoringContext monitoringContext;	
	
	@RequestMapping(value= "/common/board/boardMan.view")
	private String viewList(HttpServletRequest request, @RequestParam(value = "cmd", required = false ) String cmd ) throws Exception {
		if (cmd == null || "LIST".equals(cmd.toUpperCase())){
			cmd = "";
		}else {
			cmd = CamelCaseUtil.converCamelCase(cmd);
		}
		String path = request.getServletPath();
		return path.split("[.]")[0]+cmd;
	}
	
	@RequestMapping(value= "/common/board/boardMan.file", params = "cmd=LIST")
	private String viewList2(HttpServletRequest request, @RequestParam(value = "cmd", required = false ) String cmd ) throws Exception {
        // forward는 MenuInterceptor를 타지 않음
        //메뉴설정
        String menuPath = menuManService.getPosition(request);
        String menuAuth = menuManService.getMenuAuth(request);
    	request.setAttribute("rmsMenuPath", menuPath);
    	request.setAttribute("rmsMenuAuth", menuAuth);
    	request.setAttribute("rmsDefaultRowNum", "20");
    	request.setAttribute("rmsDefaultRowList", "10,20,30");

		String path = request.getServletPath();
		return path.split("[.]")[0];
	}
	
	/**
	 * @param request
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping(value= "/common/board/boardMan.json", params = "cmd=LIST")
	private ModelAndView selectList(HttpServletRequest request,
			JsonPageVo pageVo ,@RequestParam HashMap<String,Object> paramMap) throws Exception {
		HashMap map = service.selectList( pageVo.getStartNum(), pageVo.getEndNum(), paramMap,"TSEAIRB01");
		
		pageVo.setTotalCount((Integer)map.get("totalCount"));
		
		Map resultMap = new HashMap();
		resultMap.put("total"  , pageVo.getTotal());  //전체 페이지수
		resultMap.put("page"   , pageVo.getPage());   //현재 페이지수
		resultMap.put("records", pageVo.getTotalCount());//전체 레코드건수	
		resultMap.put("rows"   , map.get("list"));
		ModelAndView modelAndView = new ModelAndView("jsonView",resultMap);		
		return modelAndView;
	}
	
	@RequestMapping(value= "/common/board/boardMan.json",params = "cmd=DETAIL")
	private ModelAndView selectDetail(HttpServletRequest request,
			HttpServletResponse response, int seqNo, String replay) throws Exception {
		HashMap map = null;
		String userId = SessionManager.getUserId(request);
		if(seqNo > 0) {
			map = (HashMap)service.selectDetail(seqNo,userId,"TSEAIRB01");
			if("1".equals(replay)) {
				map.put("replay", "1");
			}
		}
		else {
			map = new HashMap();
			map.put("author", userId);
		}
		ModelAndView modelAndView = new ModelAndView("jsonView",map);	
		return modelAndView;
	}
	
//	@RequestMapping(value= "/common/board/boardMan.json",params = "cmd=INSERT")
//	public ModelAndView insert(HttpServletRequest request,
//			HttpServletResponse response,@RequestParam HashMap<String,Object> map) throws Exception {
//		service.insert(map);
//		ModelAndView modelAndView = new ModelAndView("jsonView");		
//		return modelAndView;
//	}	
//	
//	@RequestMapping(value= "/common/board/boardMan.json",params = "cmd=UPDATE")
//	public ModelAndView update(HttpServletRequest request,
//			HttpServletResponse response,@RequestParam HashMap<String,Object> map) throws Exception {
//    	service.update(map);
//		ModelAndView modelAndView = new ModelAndView("jsonView");		
//		return modelAndView;
//	}
	
	@RequestMapping(value= "/common/board/boardMan.json",params = "cmd=DELETE")
	public ModelAndView delete(HttpServletRequest request,
			HttpServletResponse response,@RequestParam HashMap<String,Object> map) throws Exception {
		//HashMap<String, Object> paramMap = new HashMap<String, Object>();
		service.delete(map,"TSEAIRB01");
		ModelAndView modelAndView = new ModelAndView("jsonView");		
		return modelAndView;
	}	
	
	@RequestMapping(value= "/common/board/boardMan.file", params = "cmd=INSERT", method=RequestMethod.POST)
    public String insert(MultipartHttpServletRequest request, @RequestParam("file") MultipartFile file)throws Exception{
		HashMap paramMap = upload( request,  file);
		
		String userId = SessionManager.getUserId(request);
		paramMap.put("author", userId);
		DataSourceContextHolder.setDataSourceType(DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.META));
		service.insert(paramMap,"TSEAIRB01");
		
        // forward는 MenuInterceptor를 타지 않음
        //메뉴설정
        String menuPath = menuManService.getPosition(request);
        String menuAuth = menuManService.getMenuAuth(request);
    	request.setAttribute("rmsMenuPath", menuPath);
    	request.setAttribute("rmsMenuAuth", menuAuth);
    	request.setAttribute("rmsDefaultRowNum", "20");
    	request.setAttribute("rmsDefaultRowList", "10,20,30");
    	
		String path = request.getServletPath();
		path = path.split("[.]")[0];
		return path;
	}
	
	@RequestMapping(value= "/common/board/boardMan.file", params = "cmd=UPDATE", method=RequestMethod.POST)
    public String update(MultipartHttpServletRequest request, @RequestParam("file") MultipartFile file)throws Exception{
		HashMap paramMap = upload( request,  file);
		
		DataSourceContextHolder.setDataSourceType(DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.META));
		
		HashMap map = null;
		int iSeqNo = 0;
		String seqNo = (String)paramMap.get("seqNo");
		String location = (String)paramMap.get("location");
		String filename = (String)paramMap.get("filename");
		try {
			iSeqNo = Integer.parseInt(seqNo);
		}
		catch(Exception ex) {
			logger.warn("SeqNo is not number : " + seqNo);
		}
		
		// delete previous file
		if(iSeqNo > 0 
				&& (!StringUtils.isEmpty(location) && !StringUtils.isEmpty(filename)) ) {
			map = (HashMap)service.selectDetail(iSeqNo,"","TSEAIRB01");
			String pLocation = (String)map.get("LOCATION");
			File f = new File(pLocation);
			if(f.exists() && f.isFile()) {
				f.delete();
				logger.warn("Delete Previous File : orgNo="+seqNo+", filename="+ filename +", location="+location);
			}
		}
		
		service.update(paramMap,"TSEAIRB01");
		
        // forward는 MenuInterceptor를 타지 않음
        //메뉴설정
        String menuPath = menuManService.getPosition(request);
        String menuAuth = menuManService.getMenuAuth(request);
    	request.setAttribute("rmsMenuPath", menuPath);
    	request.setAttribute("rmsMenuAuth", menuAuth);
    	request.setAttribute("rmsDefaultRowNum", "20");
    	request.setAttribute("rmsDefaultRowList", "10,20,30");
    	
		String path = request.getServletPath();
		path = path.split("[.]")[0] ;
		return path;
	}
	
	@RequestMapping(value= "/common/board/boardMan.file", params = "cmd=DOWNLOAD")
    public void fileDownload(HttpServletRequest request,
			HttpServletResponse response, int seqNo) throws Exception {
		HashMap map = (HashMap)service.selectDetail(seqNo,"","TSEAIRB01");
		
		if(map == null) {
			return;
		}
		String location = (String)map.get("LOCATION");
		String filename = (String)map.get("FILENAME");
		
		logger.info("DOWNLOAD : seqNo=" + seqNo + ", location="+ location + ", filename="+ filename);
		
		OutputStream os = null;
		BufferedInputStream bis = null;
		try {
			File file = new File(location);
			
			if(!file.exists()) {
				logger.warn("DOWNLOAD file not found : seqNo=" + seqNo + ", location="+ location + ", filename="+ filename+";");
				return;
			}
			
			response.setContentType("application/octet-stream");
			response.setHeader("Content-Transfer-Encoding", "binary:");
			response.setHeader("Content-Disposition", "attachment; filename=\""+ toUniCode(filename) +"\"");
			
			os = response.getOutputStream();
			bis = new BufferedInputStream(new FileInputStream(location)); 
			
			int readCnt = 0;
			byte[] buffer = new byte[512];
			
			while( (readCnt = bis.read(buffer)) != -1) {
				os.write(buffer, 0, readCnt);
				os.flush();
			}
		}
		catch(Exception ex) {
			logger.error("filedownload error, seqNo="+seqNo, ex);
		}
		finally {
			if(bis != null) bis.close();
			if(os != null) os.close();
		}
	}
	
	private String toUniCode(String value) throws UnsupportedEncodingException {
		return new String(value.getBytes(),"8859_1");
	}
	
	private HashMap upload(MultipartHttpServletRequest request, MultipartFile file) throws Exception{
		String orgFileName = "";
		String fileName = "";
		String uploadedFileName = "";
		String fileExtension = "";
		String name = "";
 		String subPath = "/attachfile/";
 		
 		//LOG 파일 위치 프라퍼티로 
        String defaultLogPath = monitoringContext.getStringProperty(
                MonitoringContext.DEFAULT_LOG_PATH, "/fslog/eai/");
    	
        String srcFilePath = defaultLogPath + subPath;
        
        logger.info("srcFilePath : "+srcFilePath);
    	
        // 0. create dir
        File dir = new File(srcFilePath);
        if (dir != null && !dir.exists()) {
            boolean success = dir.mkdirs();
            if (!success) {
                LogLog.error("Failed to create directory structure: " + dir);
            }
        }

        int idx1 = 0;
 		int idx2 = 0;

 		//1. file upload 
 		if(file != null) { 			 
 			orgFileName = file.getOriginalFilename();
 			orgFileName=orgFileName.substring(orgFileName.lastIndexOf("\\")+1);
	 		
	 		if(orgFileName != null && orgFileName.trim().length() > 0) {
	 			idx1 = orgFileName.lastIndexOf(File.pathSeparator);
	 			if(idx1 < 0) {
	 				idx1 = orgFileName.lastIndexOf("\\");
	 			}
	 			idx2 = orgFileName.lastIndexOf(".");
				
	 			fileName = orgFileName.substring(idx1+1);
	 			fileExtension = "."+orgFileName.substring(idx2+1);
				
				UUID uuid = UUID.randomUUID();
		 		name = uuid.toString();
				BufferedOutputStream stream = null;
	            try {
	            	uploadedFileName = srcFilePath +name+fileExtension;
	                byte[] bytes = file.getBytes();
	                stream =new BufferedOutputStream(new FileOutputStream(new File(uploadedFileName)));
	                stream.write(bytes);
	            } catch (Exception e) {
	                logger.error(e);
	            } finally{
	            	if (stream != null)try {stream.close();} catch (IOException e) {}
	            }
	       } else {
	            // file is empty
	    	   orgFileName = "";
	    	   uploadedFileName = "";
	        }
 		}
 		String userId = SessionManager.getUserId(request);
 		String userName = SessionManager.getUserName(request);
 		// getparameter & save board item
 		String seqNo = getStringParameter(request,"seqNo", "0");
//	    String author = getStringParameter(request,"author", userId);
//	    String authorName = getStringParameter(request,"authorName", userName);
	    String title = getStringParameter(request,"title", "");
	    String ctnt = getStringParameter(request,"ctnt", "");
	    String sortSeq = getStringParameter(request,"sortSeq", "");
	    String lvl = getStringParameter(request,"lvl", "");
	    String lvlNo = getStringParameter(request,"lvlNo", "");
	    
	    String menuId = getStringParameter(request,"menuId", "");
	    
	    HashMap paramMap = new HashMap();
		paramMap.put("seqNo", seqNo);
		paramMap.put("author", userId);
		paramMap.put("authorName", userName);
		paramMap.put("title", title);
		paramMap.put("ctnt", ctnt);
		
		paramMap.put("location", uploadedFileName);
//		paramMap.put("regDate", DatetimeUtil.getCurrentDate());
//		paramMap.put("readCnt", 0);
		paramMap.put("sortSeq", sortSeq);
		paramMap.put("lvl", lvl);
		paramMap.put("lvlNo", lvlNo);
//		paramMap.put("answer", "0");
		paramMap.put("filename", fileName);
	
		paramMap.put("menuId", menuId);
		
		return paramMap;
	}
	
	public String getStringParameter(ServletRequest request, String name, String defaultVal)
    {
        String val = request.getParameter(name);
        if(val == null) { 
        	val = defaultVal;
        }
        if("ctnt".equals(name)) {
        	logger.info("ctnt["+val.length()+"] = "+ val);
        }
        return val;
    }
}