package egovframework.com.cmm.util;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import egovframework.com.cmm.EgovWebUtil;
import egovframework.com.cmm.model.EgovFormBasedFileVo;

/**
 * @Class Name  : EgovFileUploadUtil.java
 * @Description : Spring 기반 File Upload 유틸리티
 * @Modification Information
 *
 *  수정일               수정자            수정내용
 *  ----------   --------   ---------------------------
 *  2009.08.26   한성곤            최초 생성
 *  2018.08.17   신용호            uploadFilesExt(확장자 기록) 추가
 *  2019.12.06   신용호            checkFileExtension(), checkFileMaxSize() 추가
 *  2020.08.05   신용호            uploadFilesExt Parameter 수정
 *  2021.02.16   신용호            WebUtils.getNativeRequest(request,MultipartHttpServletRequest.class);
 *
 * @author 공통컴포넌트 개발팀 한성곤
 * @since 2009.08.26
 * @version 1.0
 * @see
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class EgovFileUploadUtil extends EgovFormBasedFileUtil {

	/**
	 * 파일을 Upload(확장명 저장 및 확장자 제한) 처리한다.
	 *
	 * @param mptRequest
	 * @param where
	 * @param extensionWhiteList
	 * @return List<EgovFormBasedFileVo>
	 * @throws Exception
	 */
	public static List<EgovFormBasedFileVo> uploadFilesExt(MultipartHttpServletRequest mptRequest, String where,
		String extensionWhiteList) throws Exception {
		List<EgovFormBasedFileVo> list = new ArrayList<>();
		if(mptRequest == null)	return list;

		Iterator<?> fileIter = mptRequest.getFileNames();

		while (fileIter.hasNext()) {
			MultipartFile mFile = mptRequest.getFile((String)fileIter.next());
			if(mFile == null) continue;

			String tmp = mFile.getOriginalFilename();
			if(tmp == null)	continue;

			if (tmp.lastIndexOf("\\") >= 0) {
				tmp = tmp.substring(tmp.lastIndexOf("\\") + 1);
			}

			String ext;
			if (tmp.lastIndexOf(".") > 0) {
				ext = getFileExtension(tmp).toLowerCase();
			} else {
				throw new SecurityException("Unacceptable file extension."); // 허용되지 않는 확장자 처리
			}
			if (extensionWhiteList.indexOf(ext) < 0) {
				throw new SecurityException("Unacceptable file extension."); // 허용되지 않는 확장자 처리
			}

			EgovFormBasedFileVo vo = new EgovFormBasedFileVo();
			vo.setFileName(tmp);
			vo.setContentType(mFile.getContentType());
			vo.setServerSubPath(getTodayString());
			vo.setPhysicalName(getPhysicalFileName() + "." + ext);
			vo.setSize(mFile.getSize());

			if (tmp.lastIndexOf(".") >= 0) {
				vo.setPhysicalName(vo.getPhysicalName()); // 2012.11 KISA 보안조치
			}

			if (mFile.getSize() > 0) {
				try (InputStream is = mFile.getInputStream();){
					saveFile(is, new File(EgovWebUtil.filePathBlackList(
						where + SEPERATOR + vo.getServerSubPath() + SEPERATOR + vo.getPhysicalName())));
				}
				list.add(vo);
			}
		}
		return list;
	}

	/**
	 * 파일 확장자를 추출한다.
	 *
	 * @param fileNamePath
	 * @return 확장자 : "" 또는 추출된 확장자
	 */
	public static String getFileExtension(String fileNamePath) {

		if (fileNamePath == null) {
			return "";
		}
		return fileNamePath.substring(fileNamePath.lastIndexOf(".") + 1, fileNamePath.length());
	}

	/**
	 * 파일 확장자의 허용유무를 검증한다.
	 *
	 * @param fileNamePath
	 * @param whiteListExtensions : ex) .png.pdf.txt
	 * @return true : 허용
	 * @return true : 불가
	 */
	public static boolean checkFileExtension(String fileNamePath, String whiteListExtensions) {
		String extension = getFileExtension(fileNamePath);

		if ("".equals(extension)) {
			return false;
		}

		if (whiteListExtensions == null) {
			return false;
		}
		if ("".equals(whiteListExtensions)) {
			return false;
		}

		return whiteListExtensions.contains("." + extension);
	}

	/**
	 * 최대 파일 사이즈 허용유무를 검증한다.
	 *
	 * @param multipartFile
	 * @param maxFileSize : ex) 1048576 = 1M , 1K = 1024
	 * @return true : 허용
	 * @return true : 불가
	 */
	public static boolean checkFileMaxSize(MultipartFile multipartFile, long maxFileSize) {

		if (multipartFile == null) return false;

		return (multipartFile.getSize() <= maxFileSize);
	}

}
