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

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.core.io.Resource;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;

public class FileIoUtils {
	/**
	 * @return d:/Downloads/aaa.txt --> aaa.txt
	 */
	public static String getName(String filePath) {
		return FilenameUtils.getName(filePath);
	}

	/**
	 * @return d:/Downloads/aaa.txt --> txt
	 */
	public static String getExtension(String filePath) {
		return FilenameUtils.getExtension(filePath);
	}

	/**
	 * @return d:/Downloads/aaa.txt --> d:/Downloads
	 */
	public static String getDirName(String filePath) {
		int idx = filePath.indexOf(getName(filePath));
		return filePath.substring(0, idx > 0 ? idx - 1 : 0);
	}

	/**
	 * @return d:/Downloads/aaa.txt --> aaa
	 */
	public static String getBaseName(String filename) {
		return FilenameUtils.getBaseName(filename);
	}

	public static String streamToString(InputStream input, String encoding) {
		try {
			return IOUtils.toString(input, encoding);
		}
		catch (IOException e) {
			throw new RuntimeException(e);
		}
		finally {
			IOUtils.closeQuietly(input);
		}
	}

	public static String streamToString(InputStream input) {
		return streamToString(input, null);
	}

	public static String fileToString(File file) {
		return fileToString(file, null);
	}

	public static String fileToString(File file, String encoding) {
		try {
			return org.apache.commons.io.FileUtils.readFileToString(file, encoding);
		}
		catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	public static void stringToFile(String text, File file) {
		stringToFile(text, file, null);
	}

	public static void stringToFile(String text, File file, String encoding) {
		try {
			org.apache.commons.io.FileUtils.write(file, text, encoding);
		}
		catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * stream을 복사하고 두 스트림 모두 닫는다.
	 */
	public static void copy(InputStream src, OutputStream dst) {
		try {
			IOUtils.copy(src, dst);
		}
		catch (IOException e) {
			throw new RuntimeException(e);
		}
		finally {
			IOUtils.closeQuietly(src);
			IOUtils.closeQuietly(dst);
		}
	}

	public static void copy(String src, String dst) {
		try {
			org.apache.commons.io.FileUtils.copyFile(new File(src), new File(dst));
		}
		catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	public static File mkDirIfNotExist(String dir) {
		File file = new File(dir);
		if (!file.isDirectory())
			file.mkdirs();
		return file;
	}

	public static void fileDownload(Resource res
			, HttpServletRequest request, HttpServletResponse response) throws IOException {
		fileDownload(res.getFile(), request, response);
	}

	public static void setDownloadHeader(String fileName, HttpServletRequest request, HttpServletResponse response) throws IOException {
		// response header
		String userAgent = request.getHeader("User-Agent");
		String fname, dispos;
		if (userAgent.indexOf("MSIE 5.5") >= 0) {
			fname = URLEncoder.encode(fileName, "UTF-8");
			dispos = String.format("filename=\"%s\"", fname);
		}
		else if (userAgent.indexOf("MSIE") >= 0) {
			fname = URLEncoder.encode(fileName, "UTF-8");
			dispos = String.format("attachment; filename=\"%s\"", fname);
		}
		else {
			fname = new String(fileName.getBytes("EUC-KR"), "8859_1");
			dispos = String.format("attachment; filename=\"%s\"", fname);
		}

		response.setHeader("Content-Disposition", dispos);
		response.setHeader("Content-Transfer-Encoding", "binary;");
	}

	public static void fileDownload(File file, HttpServletRequest request, HttpServletResponse response) throws IOException {
		String fileName = file.getName();
		long fileSize = file.length();
		InputStream in = new FileInputStream(file);

		// response header
		setDownloadHeader(fileName, request, response);
		response.setHeader("Content-Length", String.valueOf(fileSize));

		// write to response
		OutputStream out = response.getOutputStream();
		try {
			IOUtils.copy(in, out);
		}
		finally {
			IOUtils.closeQuietly(in);
			IOUtils.closeQuietly(out);
		}
	}

	public static boolean fileUpload(MultipartFile upfile, File savefile) throws IOException {
		return fileUpload(upfile, savefile, false);
	}

	public static boolean fileUpload(MultipartFile upfile, File savefile, boolean append) throws IOException {
		if (upfile == null || upfile.isEmpty())
			return false;

		String saveDir = getDirName(savefile.getAbsolutePath());
		mkDirIfNotExist(saveDir);
		if (!append) {
			upfile.transferTo(savefile);
		}
		else {
			InputStream in = null;
			OutputStream out = null;
			try {
				in = upfile.getInputStream();
				out = new FileOutputStream(savefile, true);
				IOUtils.copy(in, out);
			}
			finally {
				IOUtils.closeQuietly(in);
				IOUtils.closeQuietly(out);
			}
		}
		return true;
	}


	/**
	 * @param crext "."를 포함해야 정확한 결과를 얻는다.
	 */
	public static boolean isExtension(String fname, String... exts) {
		if (fname == null) return false;
		for (String ext : exts) {
			if (fname.toLowerCase().endsWith(ext.toLowerCase()))
				return true;
		}
		return false;
	}

	/**
	 * 파일이 없으면 생성, 있으면 추가.
	 */
	public static void writeLine(File file, String line) {
		try {
			org.apache.commons.io.FileUtils.writeLines(file, Arrays.asList(line), true);
		}
		catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	public static void writeLines(File file, List<String> lines) {
		try {
			org.apache.commons.io.FileUtils.writeLines(file, lines, true);
		}
		catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

}