package incheon.res.rdm.com.attachfile.service;


import incheon.com.cmm.service.EgovFileMngUtil;
import incheon.com.utl.fcc.service.EgovStringUtil;
import incheon.res.rdm.com.attachfile.vo.RdmComAttachfileVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.log4j.Logger;
import org.egovframe.rte.fdl.property.EgovPropertyService;
import org.springframework.stereotype.Component;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

@Component("RdmFileMngUtil")
@RequiredArgsConstructor
public class RdmFileMngUtil {

    public static final int BUFF_SIZE = 2048;
	private final org.springframework.core.env.Environment env;
	private static final Logger LOG = Logger.getLogger(EgovFileMngUtil.class.getName());

    /**
     * 첨부파일에 대한 목록 정보를 취득한다.
     */
    public List<RdmComAttachfileVO> parseFileInf(HttpServletRequest requst, Map<String, MultipartFile> files, String datSeq, String tlbNam, String[] atfCodeList) throws Exception {
	String brdKey = datSeq;
	
	String[] atfcode = atfCodeList;
	
	String storePathString = env.getProperty("res.fileLocation");

	Iterator<Entry<String, MultipartFile>> itr = files.entrySet().iterator();
	MultipartFile file;
	String filePath = "";
	List<RdmComAttachfileVO> result  = new ArrayList<>();
	RdmComAttachfileVO fvo;

	int cnt = 0;
	while (itr.hasNext()) {
		String newName = EgovStringUtil.getTimeStamp()+cnt;
		String addfilePath = newName.substring(0,6);

		File saveFolder = new File(storePathString+File.separator+addfilePath);
		
		if (!saveFolder.exists() || saveFolder.isFile()) {
		    saveFolder.mkdirs();
		}

	    Entry<String, MultipartFile> entry = itr.next();

	    file = entry.getValue();
	    String orginFileName = file.getOriginalFilename();
	    
	    String[] arryKey = entry.getKey().split("_");
	    String key = arryKey[1];
	    
	    
	    //--------------------------------------
	    // 원 파일명이 없는 경우 처리
	    // (첨부가 되지 않은 input file type)
	    //--------------------------------------
	    if ("".equals(orginFileName)) {
	    	cnt++;
	    	continue;
	    }
	    ////------------------------------------

	    int index = orginFileName.lastIndexOf(".");
	    //String fileName = orginFileName.substring(0, index);
	    String fileExt = orginFileName.substring(index + 1);
	    
	    long _size = file.getSize();

	    if (!"".equals(orginFileName)) {
			if(tlbNam.equalsIgnoreCase("CMT_POPUP_NTCE")){
				filePath = storePathString + File.separator + addfilePath + File.separator + newName + "." + fileExt;
			}else {
				filePath = storePathString + File.separator + addfilePath + File.separator + newName;
			}
			file.transferTo(new File(filePath));
	    }
	    
	    fvo = new RdmComAttachfileVO();
	    fvo.setDatSeq(brdKey);
	    fvo.setTblNam(tlbNam);
	    fvo.setAdfNam(newName+"."+fileExt);
	    fvo.setOrgNam(orginFileName);
	    fvo.setAdfSiz(BigDecimal.valueOf(_size));
	    fvo.setSubSeq(new BigDecimal(0));
		if(tlbNam.equalsIgnoreCase("CMT_POPUP_NTCE")){
			fvo.setAdfPth(storePathString + File.separator + addfilePath + File.separator + newName+ "." + fileExt);
		}else {
			fvo.setAdfPth(storePathString + File.separator + addfilePath + File.separator + newName);
		}
	    if(key != null && !key.equals("") && !key.equals("undefined")){
	    	fvo.setAtfCde(key);
	    }else{
	    	
	    }
	    result.add(fvo);
	    cnt++;
	}

		return result;
    }
    
    /**
     * 첨부파일에 대한 목록 정보를 취득한다.
     */
    public List<RdmComAttachfileVO> parseFileInf(HttpServletRequest requst, Map<String, MultipartFile> files, String datSeq, String tlbNam, String[] atfCodeList, int ddwSeq) throws Exception {
	String brdKey = datSeq;
	
	String[] atfcode = atfCodeList;
	
	String storePathString = env.getProperty("res.fileLocation");

	Iterator<Entry<String, MultipartFile>> itr = files.entrySet().iterator();
	MultipartFile file;
	String filePath = "";
	List<RdmComAttachfileVO> result  = new ArrayList<RdmComAttachfileVO>();
	RdmComAttachfileVO fvo;

	int cnt = 0;
	while (itr.hasNext()) {
		String newName = EgovStringUtil.getTimeStamp();
		String addfilePath = newName.substring(0,6);

		File saveFolder = new File(storePathString+File.separator+addfilePath);
		
		if (!saveFolder.exists() || saveFolder.isFile()) {
		    saveFolder.mkdirs();
		}

	    Entry<String, MultipartFile> entry = itr.next();

	    file = entry.getValue();
	    String orginFileName = file.getOriginalFilename();
	    
	    String[] arryKey = entry.getKey().split("_");
	    String key = arryKey[1];
	    
	    
	    //--------------------------------------
	    // 원 파일명이 없는 경우 처리
	    // (첨부가 되지 않은 input file type)
	    //--------------------------------------
	    if ("".equals(orginFileName)) {
	    	cnt++;
	    	continue;
	    }
	    ////------------------------------------

	    int index = orginFileName.lastIndexOf(".");
	    String fileExt = orginFileName.substring(index + 1);
	    
	    long _size = file.getSize();

	    if (!"".equals(orginFileName)) {
	    	filePath = storePathString + File.separator + addfilePath + File.separator + newName;
	    	file.transferTo(new File(filePath));
	    }
	    
	    fvo = new RdmComAttachfileVO();
	    fvo.setDatSeq(brdKey);
	    fvo.setTblNam(tlbNam);
	    fvo.setSubSeq(new BigDecimal(ddwSeq));
	    fvo.setAdfNam(newName+"."+fileExt);
	    fvo.setOrgNam(orginFileName);
	    fvo.setAdfPth(storePathString + File.separator + addfilePath + File.separator + newName);
	    fvo.setAdfSiz(BigDecimal.valueOf(_size));
	    if(key != null && !key.equals("") && !key.equals("undefined")){
	    	fvo.setAtfCde(key);
	    }else{
	    	
	    }
	    result.add(fvo);
	    cnt++;
	}

		return result;
    }

    /**
     * 첨부파일을 서버에 저장한다.
     */
    protected void writeUploadedFile(MultipartFile file, String newName, String stordFilePath) throws Exception {
	InputStream stream = null;
	OutputStream bos = null;
	String stordFilePathReal = (stordFilePath==null?"":stordFilePath).replaceAll("..","");
	try {
	    stream = file.getInputStream();
	    File cFile = new File(stordFilePathReal);

	    if (!cFile.isDirectory()) {
		boolean _flag = cFile.mkdir();
		if (!_flag) {
		    throw new IOException("Directory creation Failed ");
		}
	    }

	    bos = new FileOutputStream(stordFilePathReal + File.separator + newName);

	    int bytesRead = 0;
	    byte[] buffer = new byte[BUFF_SIZE];

	    while ((bytesRead = stream.read(buffer, 0, BUFF_SIZE)) != -1) {
		bos.write(buffer, 0, bytesRead);
	    }
	} catch (FileNotFoundException fnfe) {
		LOG.error("File not found");
	} catch (IOException ioe) {
		LOG.error("File not found");
	} finally {
	    if (bos != null) {
			try {
				bos.close();
			} catch (IOException e) {
				LOG.error("IGNORED");
			}
	    }
	    if (stream != null) {
			try {
				stream.close();
			} catch (IOException e) {
				LOG.error("IGNORED");
			}
	    }
	}
    }	
	
    /**
     * 서버의 파일을 다운로드한다.
     */
    public static void downFile(HttpServletRequest request, HttpServletResponse response) throws Exception {

    String downFileName = EgovStringUtil.isNullToString(request.getAttribute("downFile")).replaceAll("..","");
    String orgFileName = EgovStringUtil.isNullToString(request.getAttribute("orgFileName")).replaceAll("..","");

	File file = new File(downFileName);

	if (!file.exists()) {
	    throw new FileNotFoundException(downFileName);
	}

	if (!file.isFile()) {
	    throw new FileNotFoundException(downFileName);
	}

	byte[] b = new byte[BUFF_SIZE]; //buffer size 2K.
    String fName = (new String(orgFileName.getBytes("UTF-8"), "ISO-8859-1")).replaceAll("\r\n","");
	response.setContentType("application/x-msdownload");
	response.setHeader("Content-Disposition", "attachment; filename=" + fName);
	response.setHeader("Content-Transfer-Encoding", "binary");
	response.setHeader("Pragma", "no-cache");
	response.setHeader("Expires", "0");

	BufferedInputStream fin = null;
	BufferedOutputStream outs = null;

	try {
		fin = new BufferedInputStream(new FileInputStream(file));
	    outs = new BufferedOutputStream(response.getOutputStream());
	    int read = 0;

		while ((read = fin.read(b)) != -1) {
		    outs.write(b, 0, read);
		}
	} finally {
			if (outs != null) {
				try {
					outs.close();
				} catch (IOException e) {
					LOG.error("IGNORED");
				}
			}
			if (fin != null) {
				try {
					fin.close();
				} catch (IOException e) {
					LOG.error("IGNORED");
				}
			}
		}
    }

    /**
     * 파일을 실제 물리적인 경로에 생성한다.
     */
    protected static void writeFile(MultipartFile file, String newName, String stordFilePath) throws Exception {
	InputStream stream = null;
	OutputStream bos = null;
	newName = EgovStringUtil.isNullToString(newName).replaceAll("..", "");
	stordFilePath = EgovStringUtil.isNullToString(stordFilePath).replaceAll("..", "");
	try {
	    stream = file.getInputStream();
	    File cFile = new File(stordFilePath);

	    if (!cFile.isDirectory())
		cFile.mkdir();

	    bos = new FileOutputStream(stordFilePath + File.separator + newName);

	    int bytesRead = 0;
	    byte[] buffer = new byte[BUFF_SIZE];

	    while ((bytesRead = stream.read(buffer, 0, BUFF_SIZE)) != -1) {
		bos.write(buffer, 0, bytesRead);
	    }
	} catch (FileNotFoundException fnfe) {
		LOG.error("File not found");
	} catch (IOException ioe) {
		LOG.error("I/O error occurred");
	} finally {
	    if (bos != null) {
			try {
				bos.close();
			} catch (IOException e) {
				Logger.getLogger(EgovFileMngUtil.class).debug("IGNORED");
			}
	    }
	    if (stream != null) {
			try {
				stream.close();
			} catch (IOException e) {
				Logger.getLogger(EgovFileMngUtil.class).debug("IGNORED");
			}
	    }
	}
    }

    /**
     * 서버 파일에 대하여 다운로드를 처리한다.
     * @param streFileNm
     *            : 파일저장 경로가 포함된 형태
     */
    public void downFile(HttpServletResponse response, String streFileNm, String orignFileNm) throws Exception {
    String downFileName = EgovStringUtil.isNullToString(streFileNm).replaceAll("..","");
	String orgFileName = EgovStringUtil.isNullToString(orignFileNm).replaceAll("..","");

	File file = new File(downFileName);

	if (!file.exists()) {
	    throw new FileNotFoundException(downFileName);
	}

	if (!file.isFile()) {
	    throw new FileNotFoundException(downFileName);
	}

	//byte[] b = new byte[BUFF_SIZE]; //buffer size 2K.
	int fSize = (int)file.length();
	if (fSize > 0) {
	    BufferedInputStream in = null;

	    try {
		in = new BufferedInputStream(new FileInputStream(file));

    	    	String mimetype = "text/html"; //"application/x-msdownload"

    	    	response.setBufferSize(fSize);
		response.setContentType(mimetype);
		response.setHeader("Content-Disposition", "attachment; filename=" + orgFileName);
		response.setContentLength(fSize);
		FileCopyUtils.copy(in, response.getOutputStream());
	    } finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					Logger.getLogger(EgovFileMngUtil.class).debug("IGNORED");
				}
			}
	    }
	    response.getOutputStream().flush();
	    response.getOutputStream().close();
	}
    }
}
