package kr.co.uplus.ez.common.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;

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

import org.apache.commons.io.FilenameUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

public class FileUtil {

	private static int BUFFERSIZE = 1024;

	/**
	 * 폴더 생성
	 */
	public static boolean makeDir(String dir) {
		boolean bResult = false;
		File f = new File(dir);
		if (!f.exists()) {
			try {
				bResult = f.mkdirs();
				//Runtime.getRuntime().exec("chmod 775 " + dir);
			} catch (Exception e) {
				bResult = false;
			}
		}
		return bResult;
	}

	/**
	 * 파일을 지정된 경로에 지정된 이름으로 저장  후 저장여부 리턴
	 * @param file
	 * @param path
	 * @return
	 */
	public static boolean upload(MultipartFile file, String filename, String path) {
		boolean saved = true;

		String extension = FilenameUtils.getExtension(file.getOriginalFilename()).toLowerCase();
//		String fos = path + File.separatorChar + filename + "." + extension;
		String fos = path + File.separatorChar + filename;

		InputStream inputStream = null;
		OutputStream outputStream = null;

		try {
			if (file != null && file.getSize() > 0) {
				if (!existsFile(path) ) FileUtil.makeDir(path);

				inputStream = file.getInputStream();
				outputStream = new FileOutputStream(fos);
				int readBytes = 0;
				byte[] buffer = new byte[BUFFERSIZE];
				while ((readBytes = inputStream.read(buffer, 0, BUFFERSIZE)) != -1) {
					outputStream.write(buffer, 0, readBytes);
				}
				//Runtime.getRuntime().exec("chmod 775 " + saveFileName);
			}
		} catch (Exception e) {
			saved = false;
		} finally {
			close(outputStream);
			close(inputStream);
		}
		return saved;
	}

	/**
	 * 파일 업로드 후 실제 저장된 파일명을 반환한다
	 * @param file
	 * @param path
	 * @return
	 */
	public static Map<String, String> upload_newname(MultipartFile file, String path) {
		String extension = FilenameUtils.getExtension(file.getOriginalFilename()).toLowerCase();
		String newName = new SimpleDateFormat("yyyyMMddHHmmSSS").format(new Date()) + "." + extension;

		Date d = new Date(); // your date
		Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("Asia/Seoul"));
		cal.setTime(d);
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH) + 1;

		String newFilePath = path + File.separatorChar + year + File.separatorChar + month + File.separatorChar;
		String newFileName = newFilePath + newName;
		String saveFileName = newFileName;

		InputStream inputStream = null;
		OutputStream outputStream = null;

		try {
			if (file != null && file.getSize() > 0) {
				if (!existsFile(newFilePath) ) FileUtil.makeDir(newFilePath);

				inputStream = file.getInputStream();
				outputStream = new FileOutputStream(saveFileName);
				int readBytes = 0;
				byte[] buffer = new byte[BUFFERSIZE];
				while ((readBytes = inputStream.read(buffer, 0, BUFFERSIZE)) != -1) {
					outputStream.write(buffer, 0, readBytes);
				}

				//Runtime.getRuntime().exec("chmod 775 " + saveFileName);
			}
		} catch (Exception e) {
			e.printStackTrace();
			newName = "";
		} finally {
			close(outputStream);
			close(inputStream);
		}

		Map<String, String> info = new HashMap<String, String>();
		info.put("fileName", newName);
		info.put("filePath", newFilePath);
		return info;
	}

	/**
	 * 파일 존재 여부
	 */
	public static boolean existsFile(String file) {
		File f = new File(file);
		return f.exists();
	}

	/**
	 * HTTP 파일 다운로드
	 */
	public static void download(HttpServletRequest request, HttpServletResponse response, String filename, File file) {
		download(request, response, filename, file, false);
	}

	/**
	 * 다운로드
	 */
	private static void download(HttpServletRequest request, HttpServletResponse response, String filename, File file, boolean isDeleteOnExit) {

		if (file.exists()) {
			FileInputStream fileInStream = null;
			OutputStream outStream = null;

			try {
				String extension = FilenameUtils.getExtension(filename).toLowerCase();

				// 형태에 따른 컨텐트 타입 분류
				if      ("zip".equals(extension))								response.setContentType("application/zip");
				else if ("xls".equals(extension) || "xlsx".equals(extension))	response.setContentType("application/vnd.ms-excel;charset=UTF-8");
				else if ("ppt".equals(extension) || "pptx".equals(extension))	response.setContentType("application/x-mspowerpoint");
				else if ("doc".equals(extension) || "docx".equals(extension))	response.setContentType("application/msword");
				else if ("pdf".equals(extension))								response.setContentType("application/x-msdownload");
				else if ("jpg".equals(extension))								response.setContentType("image/jpg");
				else if ("gif".equals(extension))								response.setContentType("image/gif");
				else if ("png".equals(extension))								response.setContentType("image/png");

				response.setHeader("Buffer", "true");
				response.setHeader("Pragma", "no-cache;");
				response.setHeader("Expires", "-1;");
				response.setHeader("Content-Transfer-Encoding", "binary;");
				response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8").replaceAll("\\+", "%20") + ";");

				fileInStream = new FileInputStream(file);
				outStream = response.getOutputStream();

				int readBytes = 0;
				byte[] buffer = new byte[BUFFERSIZE * 100];

				while ((readBytes = fileInStream.read(buffer)) != -1) {
					outStream.write(buffer, 0, readBytes);
				}

				outStream.flush();
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				close(fileInStream);
				close(outStream);
				if (isDeleteOnExit) {
					file.delete();
				}
			}
		}
	}

	/**
	 * 엑셀 파일 다운로드
	 */
	public static void download(HttpServletRequest request, HttpServletResponse response, String filename, Workbook workbook) {
		OutputStream outStream = null;
		try {
			ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
			workbook.write(outByteStream);

			if (workbook instanceof SXSSFWorkbook) {
				((SXSSFWorkbook) workbook).dispose();
			}

			byte [] outArray = outByteStream.toByteArray();
			response.setContentLength(outArray.length);
			response.setContentType("application/vnd.ms-excel;charset=UTF-8");
			response.setHeader("Pragma", "no-cache;");
			response.setHeader("Expires", "-1;");
			response.setHeader("Content-Transfer-Encoding", "binary;");
			response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8").replaceAll("\\+", "%20") + ";");
			response.setHeader("Buffer", "true");

			outStream = response.getOutputStream();
			outStream.write(outArray);
			outStream.flush();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			close(outStream);
		}
	}

	/**
	 * InputStream을 종료한다.
	 */
	public static void close(InputStream stream) {
		if (stream != null) {
			try {
				stream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * OutputStream을 종료한다.
	 */
	public static void close(OutputStream stream) {
		if (stream != null) {
			try {
				stream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * FileOutputStream을 종료한다.
	 */
	public static void close(FileOutputStream stream) {
		if (stream != null) {
			try {
				stream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
