/*
 * CKEditor image upload module for Java.
 * Copyright guavatak (https://github.com/guavatak/ckeditor-upload-filter-java)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @author guavatak (https://github.com/guavatak/ckeditor-upload-filter-java)
 */
package kcg.faics.cmmn.ckeditor;

import java.io.IOException;
import java.io.PrintWriter;

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

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartRequest;

/**
 * Created by guava on 1/20/14.
 *  이미지 저장 처리 클래스
 * @author guavatak
 * @since 2014.12.04
 * @version 1.0
 * @see
 *
 * <pre>
 * << 개정이력(Modification Information) >>
 *
 *   수정일        수정자       수정내용
 *  -------       --------    ---------------------------
 *   2014.12.04	표준프레임워크	최초 적용 (패키지 변경 및 소스 정리)
 * </pre>
 */
public class CkImageSaver {
	private static final Log log = LogFactory.getLog(CkFilter.class);

	private static final String FUNC_NO = "CKEditorFuncNum";

	private String imageBaseDir;
	private String imageDomain;
	private String[] allowFileTypeArr;

	private FileSaveManager fileSaveManager;

	public CkImageSaver(String imageBaseDir, String imageDomain, String[] allowFileTypeArr, String saveManagerClass) {
		this.imageBaseDir = imageBaseDir;
		if (imageBaseDir.endsWith("/")) {
			StringUtils.removeEnd(imageBaseDir, "/");
		}
		if (imageBaseDir.endsWith("\\")) {
			StringUtils.removeEnd(imageBaseDir, "\\");
		}

		this.imageDomain = imageDomain;
		if (imageDomain.endsWith("/")) {
			StringUtils.removeEnd(imageDomain, "/");
		}

		this.allowFileTypeArr = allowFileTypeArr;

		if (StringUtils.isBlank(saveManagerClass)) {
			fileSaveManager = new DefaultFileSaveManager();
		} else {
			try {
				Class<?> klass = Class.forName(saveManagerClass);
				fileSaveManager = (FileSaveManager) klass.newInstance();
			} catch (ClassNotFoundException e) {
				log.error(e);
				throw new RuntimeException(e);
			} catch (InstantiationException e) {
				log.error(e);
				throw new RuntimeException(e);
			} catch (IllegalAccessException e) {
				log.error(e);
				throw new RuntimeException(e);
			}
		}
	}

	/**
	 * ckEditor로부터 넘어온 파일을 저장한다.
	 * 원래 소스는 Request 내의 데이터를 FileItem으로 파싱하여 파일을 저장하였으나, 
	 * 파싱하지 못하는 버그가 발생하여 MultipartRequest로 변형하였다.
	 * 
	 * @param request Request 객체
	 * @param response Response 객체
	 * @throws IOException IO 예외처리
	 */
	public void saveAndReturnUrlToClient(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
		// Parse the request
		try {
			MultipartRequest req = (MultipartRequest) request;
			MultipartFile f = req.getFile("upload");
			
			String errorMessage = null;
			String relUrl = null;

			if (isAllowFileType(FilenameUtils.getName(f.getOriginalFilename()))) {
				relUrl = fileSaveManager.saveFile(f, imageBaseDir, imageDomain);

			} else {
				errorMessage = "Restricted Image Format";
			}

			StringBuffer sb = new StringBuffer();
			sb.append("<script type=\"text/javascript\">\n");
			sb.append("window.parent.CKEDITOR.tools.callFunction(").append(request.getParameter(FUNC_NO)).append(", '");
			sb.append(relUrl);
			if (errorMessage != null) {
				sb.append("', '").append(errorMessage);
			}
			sb.append("');\n </script>");

			response.setContentType("text/html");
			response.setHeader("Cache-Control", "no-cache");
			PrintWriter out = response.getWriter();

			out.print(sb.toString());
			out.flush();
			out.close();

		} catch (Exception e) {
			log.error(e);
		}
	}

	protected boolean isAllowFileType(String fileName) {
		boolean isAllow = false;
		if (allowFileTypeArr != null && allowFileTypeArr.length > 0) {
			for (String allowFileType : allowFileTypeArr) {
				if (StringUtils.equalsIgnoreCase(allowFileType, StringUtils.substringAfterLast(fileName, "."))) {
					isAllow = true;
					break;
				}
			}
		} else {
			isAllow = true;
		}

		return isAllow;
	}
}
