package WDU.CMM.CMMN;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import java.net.URLDecoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.Path;

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.servlet.ModelAndView;

import egovframework.ext.wdu.Constants;
import egovframework.ext.wdu.dao.CommonDAO;
import egovframework.ext.wdu.service.CommonService;
import egovframework.ext.wdu.utils.ParamUtil;

import com.ibatis.sqlmap.client.SqlMapClient;
import com.isomorphic.datasource.BasicDataSource;
import com.isomorphic.datasource.DSRequest;
import com.isomorphic.datasource.DSResponse;
import com.isomorphic.servlet.ISCFileItem;


@Controller
@RequestMapping(value="/CMM_CMMN_FILE.do")
public class CMM_CMMN_FILE extends BasicDataSource {
	private Log log = LogFactory.getLog(this.getClass());
	
	/** 공통 일반 서비스 */
	@Resource(name = "commonService")
	private CommonService commonService;
	
	/** 공통 일반 데이타베이스 액세스 객체 */
	@Resource(name = "commonDAO")
	private  CommonDAO commonDao = new CommonDAO();
	
	private static  SqlMapClient sqlMap ;
	
	private static final String FILE_SEPARATOR = System.getProperty("file.separator"); 
	private static final String PARAM_SYS_CD          = "SYS_CD";
	private static final String PARAM_PARNTS_TABLE_NM = "PARNTS_TABLE_NM";
	private static final String PARAM_UPLOAD_ID       = "UPLOAD_ID";
	
	
	@Override
	public DSResponse executeFetch (DSRequest  dsRequest) throws Exception  {
		DSResponse dsResponse = new DSResponse(this);
		try {
			
		
			log.debug("executeFetch");
			
			log.debug(dsRequest.getCriteria());
			log.debug(dsRequest.getValues());
			Map fileMap = dsRequest.getValues();
			
			
			if(!fileMap.containsKey(PARAM_UPLOAD_ID)){
				log.debug("not contaions");
				return dsResponse.setData(new ArrayList());
			}
			
			
			HashMap<String, Object> paramMap = new HashMap<String, Object>();
			paramMap.put(PARAM_UPLOAD_ID, fileMap.get(PARAM_UPLOAD_ID).toString());
			paramMap.put(PARAM_PARNTS_TABLE_NM, fileMap.get(PARAM_PARNTS_TABLE_NM).toString());
			paramMap.put(PARAM_SYS_CD, fileMap.get(PARAM_SYS_CD).toString());
			
			
			
			
			
			
			List result = (List)commonDao.selectMultiData("CMM_CMMN_FILE_UPDOWN.selectFileUploadData", paramMap);
			
			
			Map record = new HashMap();
			Iterator iterator = result.iterator();
			
			while(iterator.hasNext()){
				record = (Map)iterator.next();
				record.put("id", record.get("FILE_ID").toString());
				//URLDecoder.decode(record.get("REAL_FILE_NM").toString(), "UTF-8");
				record.put("file_filename", record.get("REAL_FILE_NM").toString());
				//record.put("file_filename", URLDecoder.decode(record.get("REAL_FILE_NM").toString(), "UTF-8"));
				record.put("file_filesize", record.get("FILE_SIZE").toString());
				
	
			}
			dsResponse.setData(result);
		} catch ( Exception e )
		{
			e.printStackTrace();
			
		} finally {
			
		}
		
		
		return dsResponse;
	}
	
	@Override
	public DSResponse execute (DSRequest  dsRequest) throws Exception  {
		DSResponse dsResponse = new DSResponse(this);

		ServletContext conext = dsRequest.getServletContext();
		WebApplicationContext wContext = WebApplicationContextUtils.getWebApplicationContext(conext);
		sqlMap = (SqlMapClient)wContext.getBean("sqlMapClient");
		commonDao.setSqlMapClient(sqlMap);

		String operationType = dsRequest.getOperationType();
		
		if (this.log.isDebugEnabled()) {
			this.log.debug("===============FILE WORK START==================");
			this.log.debug(operationType);
			
			
		}
		if(operationType.equals("viewFile")){

			dsResponse = this.executeDownloadFile(dsRequest);
		}
		else if(operationType.equals("downloadFile")){

			dsResponse = this.executeDownloadFile(dsRequest);
		}
		else if(operationType.equals("fetch")){
			
			dsResponse = this.executeFetch(dsRequest);

		}
		else if(operationType.equals("add")){
			
			dsResponse = this.executeAdd(dsRequest);
		}
		else if(operationType.equals("update")){
			
		}
		else if(operationType.equals("remove")){
			
			dsResponse = this.executeRemove(dsRequest);
		}
		
		if (this.log.isDebugEnabled()) {
			this.log.debug("===============FILE WORK END==================");
			
		}
		
		return dsResponse;
	}
	
	@Override
	public DSResponse executeAdd (DSRequest  dsRequest) throws Exception  {
		DSResponse dsResponse = new DSResponse(this);
	
		Map fileMap = dsRequest.getValues();
		log.debug(fileMap);
		log.debug(dsRequest.getCriteria());
		log.debug(dsRequest.getClientSuppliedValues());
		ISCFileItem fileItem = dsRequest.getUploadedFile("file");
		
		
		if(fileMap.get(CMM_CMMN_FILE.PARAM_UPLOAD_ID).equals(null)){
			log.debug("++++++++++++++++++++++++++");
			log.debug("uploadId가 없습니다.");
			log.debug("++++++++++++++++++++++++++");
		}
		
		
		
		HashMap<String, Object> paramMap = new HashMap<String, Object>();
		HashMap<String, Object> resultMap;

		SimpleDateFormat format;
		
		String streFileName = "";
		String realFileName = "";
		String fileExt      = "";
		
		String uploadRootPath  = "";
		String uploadChildPath = "";
		
		try {
			paramMap.put(PARAM_UPLOAD_ID, fileMap.get(PARAM_UPLOAD_ID).toString());
			paramMap.put(PARAM_PARNTS_TABLE_NM, fileMap.get(PARAM_PARNTS_TABLE_NM).toString());
			paramMap.put(PARAM_SYS_CD, fileMap.get(PARAM_SYS_CD).toString());
			
			resultMap = (HashMap<String, Object>) commonDao.selectSingleData("CMM_CMMN_FILE_UPDOWN.selectSysFileStorgeMInfo", paramMap);
	
			log.debug(resultMap);
			format = new SimpleDateFormat("yyyyMMdd");
			uploadRootPath  = (String)resultMap.get("STORGE_ROOT_PATH");
			uploadChildPath = FILE_SEPARATOR 
							+ paramMap.get("PARNTS_TABLE_NM") 
						    + FILE_SEPARATOR 
						    + format.format(new Date())
						    + FILE_SEPARATOR 
						    + paramMap.get(PARAM_UPLOAD_ID)
						    + FILE_SEPARATOR;
			
			realFileName = fileMap.get("file_filename").toString();
			fileExt  = realFileName.substring((realFileName.lastIndexOf('.') + 1), realFileName.length());
			
			Long nanoVal = new Long(System.nanoTime());
			streFileName = nanoVal.toString() + "." + fileExt;
			
			
			if (this.log.isDebugEnabled()) {
				this.log.debug("File : " + uploadChildPath + uploadChildPath + realFileName);
				this.log.debug("File Name : " + realFileName);
				this.log.debug("File Ext  : " + fileExt);
				this.log.debug("Storage File : " + streFileName);
			}
			
			File uploadFile = new File(uploadRootPath + uploadChildPath + streFileName);
			File uploadDir  = uploadFile.getParentFile();
			
			if (!uploadDir.isFile() && !uploadDir.isDirectory()) {
				uploadDir.mkdirs();
			}

			fileItem.write(uploadFile);
			
			dsRequest.getHttpServletRequest().getSession();
			HttpSession session = dsRequest.getHttpServletRequest().getSession(true);
			String userId = (String)session.getAttribute("USER_ID");
			String userIp = dsRequest.getHttpServletRequest().getRemoteAddr();

			paramMap.put("PARNTS_TABLE_NM", resultMap.get("PARNTS_TABLE_NM"));
			paramMap.put("REAL_FILE_NM",    realFileName);
			paramMap.put("STRE_FILE_NM",    streFileName);
			paramMap.put("FILE_SIZE",       fileItem.getSize());
			paramMap.put("FILE_STRE_PATH",  uploadChildPath);
			paramMap.put("INP_ID",          userId);
			paramMap.put("INP_IP",          userIp);

			Object file_id = commonDao.insertData("CMM_CMMN_FILE_UPDOWN.insertFileUploadData", paramMap);
			
			Map addedValue = dsRequest.getValues();
			addedValue.put("id",file_id);
			addedValue.remove("file");
			addedValue.put("file_date_created",new Date());
			dsResponse.setData(addedValue);
		
		} catch ( Exception e )
		{
			e.printStackTrace();
			
		} finally {
			
		}
		
		return dsResponse;
	}
	
	@Override
	public DSResponse executeUpdate (DSRequest  dsRequest) throws Exception  {
		DSResponse dsResponse = new DSResponse(this);
		

		return dsResponse;
	}
	
	@Override
	public DSResponse executeRemove (DSRequest  dsRequest) throws Exception  {
		DSResponse dsResponse = new DSResponse(this);
		
		HashMap<String, Object> paramMap = (HashMap<String, Object>)dsRequest.getClientSuppliedValues();
		paramMap.put("FILE_ID", paramMap.get("id").toString());
		try {
			
			commonDao.deleteData("CMM_CMMN_FILE_UPDOWN.deleteFileUploadData", paramMap);
			
			dsResponse.setData(paramMap);

		} 
		catch ( Exception e )
		{
			e.printStackTrace();
			
		} finally {
			
		}

		return dsResponse;
	}
	
	
	public DSResponse executeDownloadFile (DSRequest  dsRequest) throws Exception  {
		DSResponse dsResponse = new DSResponse(this);
		
		Map criteriaMap = dsRequest.getCriteria();
		HashMap<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("FILE_ID", criteriaMap.get("id").toString());
		byte[] bytes = null;
		String downloadRootPath  = "";
		String downloadChildPath = "";
		String downloadFileName  = "";
	
		try {
			
			HashMap<String, Object> detailMap = 
					(HashMap<String, Object>)commonDao.selectSingleData("CMM_CMMN_FILE_UPDOWN.selectDownloadFileUploadData", paramMap);
			
			String PARNTS_TABLE_NM = detailMap.get("FILE_STRE_PATH").toString().replace(FILE_SEPARATOR,"@@");
			PARNTS_TABLE_NM = PARNTS_TABLE_NM.split("@@")[1];
			detailMap.put("PARNTS_TABLE_NM",PARNTS_TABLE_NM);
			HashMap<String, Object> mMap = 
					(HashMap<String, Object>)commonDao.selectSingleData("CMM_CMMN_FILE_UPDOWN.selectSysFileStorgeMInfo", detailMap);
			
			downloadRootPath = (String)mMap.get("STORGE_ROOT_PATH");
			downloadFileName  = (String)detailMap.get("STRE_FILE_NM");
        	downloadChildPath = (String)detailMap.get("FILE_STRE_PATH");
        	
        	// 다운로드 카운트를 증가시킴
        	commonDao.update("CMM_CMMN_FILE_UPDOWN.updateDownloadCount", detailMap);
        	
        	//java 7에서 등장한 기능을 사용함.
        	Path path = Paths.get(downloadRootPath + downloadChildPath + downloadFileName);
        	bytes = Files.readAllBytes(path);
        	
        	criteriaMap.put("file",bytes);
        	//criteriaMap.put("download_filename","xxxxxxxxxxxxxxxxx");
        	criteriaMap.put("file_filesize", bytes == null ? 0 : bytes.length);
        	log.debug(criteriaMap);
        	dsResponse.setData(criteriaMap);
        	

		} 
		catch ( Exception e )
		{
			e.printStackTrace();
			
		} finally {
			
		}
		
		return dsResponse;
	}
	
	/**
	 * 파일 그룹의 정보를 가져온다.
	 * @param json
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(params = "method=getTableSpec")
	public ModelAndView getTableSpec(HttpServletRequest request, HttpServletResponse response, @RequestBody String param) 
			throws Exception{
	
		final HashMap<String, Object> ParamMap = (HashMap<String, Object>)ParamUtil.toMap(param);
		
		ModelAndView mav = new ModelAndView("jsonMapView");
		Map<String, Object> result = new HashMap<String, Object>();
		try
		{
			//+++++++++++++++++++++++++++++++++++++++++++++++++++++
			// 비지니스 로직 시작
			//+++++++++++++++++++++++++++++++++++++++++++++++++++++
			
			HashMap<String, Object> resultMap 
			= (HashMap<String, Object>)commonDao.selectSingleData("CMM_CMMN_FILE_UPDOWN.selectSysFileStorgeMInfo",ParamMap);
			
			//+++++++++++++++++++++++++++++++++++++++++++++++++++++
			// 비지니스 로직 종료
			//+++++++++++++++++++++++++++++++++++++++++++++++++++++

			mav.addObject("result",resultMap);
			mav.addObject(Constants.ERROR_CODE, Constants.ERROR_NORAML);
			mav.addObject(Constants.ERROR_MSG, "");
		} catch ( Exception e )
		{
			e.printStackTrace();
			mav.addObject(Constants.ERROR_CODE, Constants.ERROR_EXCEPTION);
			mav.addObject(Constants.ERROR_MSG, e.toString());
		} finally {
			
		}
		return mav;
		
	}
}
