package jp.co.headwaters.webappos.common;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.channels.FileChannel;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import jp.co.headwaters.webappos.common.enumation.DataTypeEnum;

import org.apache.commons.lang3.StringUtils;

public class WebAppOSUtils {

	public static String getMapperName(String target){
		if (target == null) return "";
		StringBuilder sb = new StringBuilder();
		for (String val : target.split("_")) {
			sb.append(StringUtils.capitalize(val));
		}
		sb.append("Mapper");

		return sb.toString();
	}

	public static void deleteFile(File file) {
		if (file.exists() == false) {
			return;
		}

		if (file.isFile()) {
			file.delete();
		}

		if (file.isDirectory()) {
			File[] files = file.listFiles();
			for (int i = 0; i < files.length; i++) {
				deleteFile(files[i]);
			}
			file.delete();
		}
	}

	public static void copyFile(File file, String newFilePath) {
		FileInputStream fis = null;
		FileChannel ifc = null;
		FileChannel ofc = null;
		FileOutputStream fos = null;
		try {
			// 入力元ファイルのストリームからチャネルを取得する
			fis = new FileInputStream(file);
			ifc = fis.getChannel();

			// 出力先ファイルのチャネルを取得する
			File outFile = new File(newFilePath);
			fos = new FileOutputStream(outFile);
			ofc = fos.getChannel();

			// バイトを転送します。
			ifc.transferTo(0, ifc.size(), ofc);

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (ifc != null) {
				try {
					ifc.close();
				} catch (IOException e) {
				}
			}
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
				}
			}
			if (fos != null){
				try {
					fos.close();
				} catch (IOException e) {
				}
			}
			if (ofc != null) {
				try {
					ofc.close();
				} catch (IOException e) {
				}
			}
		}
	}

	public static String removeFileExtension(String filename) {
		if (StringUtils.isEmpty(filename)){
			return filename;
		}

		int lastDotPos = filename.lastIndexOf('.');
		if (lastDotPos == -1) {
			return filename;
		} else if (lastDotPos == 0) {
			return filename;
		} else {
			return filename.substring(0, lastDotPos);
		}
	}

	 public static String convertExtensionHtmlToJsp(String target){
		if (StringUtils.isEmpty(target)){
			return target;
		}

		for (String extension : AppConstants.HTML_EXTENSION) {
			target = target.replaceAll(extension+"$", AppConstants.JSP_EXTENSION);
		}
		return target;
	}

	public static FilenameFilter getHtmlFileFilter() {
		return getFileExtensionFilter(AppConstants.HTML_EXTENSION);
	}

	public static FilenameFilter getFileExtensionFilter(String extension) {
		return getFileExtensionFilter(new String[] { extension });
	}

	public static FilenameFilter getFileExtensionFilter(String[] extensions) {
		final String[] _extensions = extensions;
		return new FilenameFilter() {
			public boolean accept(File file, String name) {
				boolean result = false;
				for (String extension : _extensions){
					if (name.endsWith(extension)) {
						result = true;
						break;
					}
				}
				return result;
			}
		};
	}

	public static Object convertDataType(String value, String dataType) {
		if (value == null || dataType == null) {
			return null;
		}

		Object result = null;
		if (DataTypeEnum.DATA_TYPE_SMALLINT.getDataType().equals(dataType)) {
			result = Short.valueOf(value);
		} else if (DataTypeEnum.DATA_TYPE_INTEGER.getDataType().equals(dataType)) {
			result = Integer.valueOf(value);
		} else if (DataTypeEnum.DATA_TYPE_BIGINT.getDataType().equals(dataType)) {
			result = Long.valueOf(value);
		} else if (DataTypeEnum.DATA_TYPE_NUMERIC.getDataType().equals(dataType)) {
			result = new BigDecimal(value);
		} else if (DataTypeEnum.DATA_TYPE_REAL.getDataType().equals(dataType)) {
			result = Float.valueOf(value);
		} else if (DataTypeEnum.DATA_TYPE_DOUBLE_PRECISION.getDataType().equals(dataType)) {
			result = Double.valueOf(value);
		} else if (DataTypeEnum.DATA_TYPE_CHARACTER_VARYING.getDataType().equals(dataType)
				|| DataTypeEnum.DATA_TYPE_CHARACTER.getDataType().equals(dataType)
				|| DataTypeEnum.DATA_TYPE_TEXT.getDataType().equals(dataType)) {
			result = value;
		} else if (DataTypeEnum.DATA_TYPE_TIMESTAMP_WITHOUT_TIME_ZONE.getDataType().equals(dataType)
				|| (DataTypeEnum.DATA_TYPE_TIMESTAMP_WITH_TIME_ZONE.getDataType().equals(dataType))) {
			try {
				// TODO:日付のフォーマット
				// TODO:これだと時間が入らない！
				result = new java.sql.Timestamp(new SimpleDateFormat("yyyy/MM/dd").parse(value).getTime());
			} catch (ParseException e) {
				// TODO:ワーニング
			}
		} else if (DataTypeEnum.DATA_TYPE_DATE.getDataType().equals(dataType)) {
			try {
				// TODO:日付のフォーマット
				result = new java.sql.Date(new SimpleDateFormat("yyyy/MM/dd").parse(value).getTime());
			} catch (ParseException e) {
				// TODO:ワーニング
			}
		} else if (DataTypeEnum.DATA_TYPE_TIME_WITHOUT_TIME_ZONE.getDataType().equals(dataType)
				|| DataTypeEnum.DATA_TYPE_TIME_WITH_TIME_ZONE.getDataType().equals(dataType)) {
			try {
				// TODO:日付のフォーマット
				result = new java.sql.Time(new SimpleDateFormat("yyyy/MM/dd").parse(value).getTime());
			} catch (ParseException e) {
				// TODO:ワーニング
			}
		} else if (DataTypeEnum.DATA_TYPE_BYTEA.getDataType().equals(dataType)) {
			result = Byte.valueOf(value.toString());
		} else if (DataTypeEnum.DATA_TYPE_BOOLEAN.getDataType().equals(dataType)) {
			result = Boolean.valueOf(value.toString());
		} else if (DataTypeEnum.DATA_TYPE_BIT.getDataType().equals(dataType)
				|| DataTypeEnum.DATA_TYPE_BIT_VARYING.getDataType().equals(dataType)) {
			result = value;
		} else {
			// TODO:サポート外の型。ワーニング
			result = null;
		}
		return result;
	}

	public static String camelToSnake(String target) {
		String convertedStr = target
				.replaceAll("([A-Z]+)([A-Z][a-z])", "$1_$2")
				.replaceAll("([a-z])([A-Z])", "$1_$2");
		return convertedStr.toLowerCase();
	}

	public static String snakeToCamel(String target) {
		Pattern p = Pattern.compile("_([a-z])");
		Matcher m = p.matcher(target.toLowerCase());

		StringBuffer sb = new StringBuffer(target.length());
		while (m.find()) {
			m.appendReplacement(sb, m.group(1).toUpperCase());
		}
		m.appendTail(sb);
		return sb.toString();
	}
}
