package kcg.faics.cmmn.file;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;

import javax.activation.MimetypesFileTypeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 파일 반환 관련 클래스.
 * 
 * @author kimnomin
 *
 */
public final class FileResponser {

	/**
	 * 생성자.
	 */
	private FileResponser() {
		
	}
	
	/**
	 * 브라우저 구분을 반환한다.
	 * 
	 * @param request
	 *            HttpServletRequest 객체
	 * @return 브라우저 구분
	 */
	private static String getBrowser(final HttpServletRequest request) {
		String header = request.getHeader("User-Agent");
		if (header.indexOf("MSIE") > -1) {
			return "MSIE";
		} else if (header.indexOf("Trident") > -1) { // IE11 문자열 깨짐 방지
			return "Trident";
		} else if (header.indexOf("Chrome") > -1) {
			return "Chrome";
		} else if (header.indexOf("Opera") > -1) {
			return "Opera";
		}
		return "Firefox";
	}

	/**
	 * Disposition 지정하기.
	 *
	 * @param filename
	 *            파일명
	 * @param request
	 *            HttpServletRequest 객체
	 * @param response
	 *            HttpServletResponse 객체
	 * @throws Exception
	 *             기본 예외 처리
	 */
	private static void setDisposition(final String filename,
			final HttpServletRequest request, final HttpServletResponse response)
			throws Exception {
		String browser = getBrowser(request);

		String dispositionPrefix = "inline; filename=";
		String encodedFilename = null;

		if (browser.equals("MSIE")) {
			encodedFilename = URLEncoder.encode(filename, "UTF-8").replaceAll("\\+", "%20");
		} else if (browser.equals("Trident")) { // IE11 문자열 깨짐 방지
			encodedFilename = URLEncoder.encode(filename, "UTF-8").replaceAll("\\+", "%20");
		} else if (browser.equals("Firefox")) {
			encodedFilename = "\"" + new String(filename.getBytes("UTF-8"), "8859_1") + "\"";
		} else if (browser.equals("Opera")) {
			encodedFilename = "\"" + new String(filename.getBytes("UTF-8"), "8859_1") + "\"";
		} else if (browser.equals("Chrome")) {
			StringBuffer sb = new StringBuffer();
			for (int i = 0; i < filename.length(); i++) {
				char c = filename.charAt(i);
				if (c > '~') {
					sb.append(URLEncoder.encode("" + c, "UTF-8"));
				} else {
					sb.append(c);
				}
			}
			encodedFilename = sb.toString();
		} else {
			// throw new RuntimeException("Not supported browser");
			throw new IOException("Not supported browser");
		}

		response.setHeader("Content-Disposition", dispositionPrefix + encodedFilename);

		if ("Opera".equals(browser)) {
			response.setContentType("application/octet-stream;charset=UTF-8");
		}
	}
	
	/**
	 * 파일 반환을 위해 Response 객체를 설정한다.
	 * 
	 * @param file 파일 객체
	 * @param fileOrgName 실제 파일명
	 * @param request HttpServletRequest 객체
	 * @param response HttpServletResponse 객체
	 */
	public static void setResponse(final File file,
			final String fileOrgName,
			final HttpServletRequest request, final HttpServletResponse response) {
		if (file == null || request == null || response == null) {
			return;
		}
		
		MimetypesFileTypeMap mimeUtil = new MimetypesFileTypeMap();
		String mimeType = mimeUtil.getContentType(fileOrgName);
		response.setContentType(mimeType);
		response.setContentLength((int) file.length());
		try {
			setDisposition(fileOrgName, request, response);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
