/*
 *
 * 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.
 */
package org.dbunitng.util;

import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

import org.dbunitng.annotations.FileType;
import org.dbunitng.exception.DbUnitNGRuntimeException;
import org.dbunitng.exception.TestDataFileNotFoundException;

/**
 * リソース関連のユーティリティ.
 * 
 * @author jyukutyo
 * 
 */
public class ResourceUtil {

	/**
	 * 拡張子からFileTypeを判断する.
	 * 
	 * @param extension
	 *            .なしの拡張子
	 * @return FileType
	 */
	public static FileType toFileType(String extension) {

		if (extension == null) {
			throw new IllegalArgumentException("Argument is null.");
		}

		FileType[] types = FileType.values();
		for (FileType type : types) {
			if (extension.toLowerCase().startsWith(type.toString())) {
				return type;
			}
		}
		return FileType.valueOf(extension);
	}

	/**
	 * 拡張子を返す.
	 * 
	 * @param pathName
	 *            パス
	 * @return 拡張子
	 */
	public static String getExtension(String pathName) {

		if (pathName == null) {
			throw new IllegalArgumentException("Argument is null.");
		}

		return pathName.substring(pathName.lastIndexOf('.') + 1);
	}

	/**
	 * リソースをストリームで返す.
	 * 
	 * @param pathName
	 *            パス
	 * @return リソース
	 */
	public static InputStream getResourceAsStream(String pathName) {
		InputStream stream =
			Thread.currentThread().getContextClassLoader().getResourceAsStream(
				pathName);
		if (stream == null) {
			throw new TestDataFileNotFoundException(pathName + " is not found.");
		}
		return stream;
	}

	/**
	 * パッケージ記述をディレクトリ階層に変換する.
	 * 
	 * <pre>
	 * replacePackageToDirectory(&quot;org.dbunitng.util.ResourceUtil&quot;) =
	 * 	&quot;org/dbunitng/util/ResourceUtil&quot;
	 * </pre>
	 * 
	 * @param fqcn
	 *            「.」区切りの文字列(完全修飾名など)
	 * @return 「/」区切りの文字列
	 */
	public static String replacePackageToDirectory(String fqcn) {

		if (fqcn == null) {
			return null;
		}

		return fqcn.replace('.', '/');
	}

	/**
	 * パッケージ記述と拡張子からファイルパスを返す.
	 * 
	 * <pre>
	 * toFilePath(&quot;aa.bbb.Ccc&quot;, &quot;xml&quot;) = &quot;aa/bbb/Ccc.xml&quot;
	 * </pre>
	 * 
	 * @param fqcn
	 *            「.」区切りの文字列(完全修飾名など)
	 * @param extension
	 *            拡張子
	 * @return ファイルパス
	 */
	public static String toFilePath(String fqcn, String extension) {

		if (extension == null) {
			throw new IllegalArgumentException(
				"Argument extension is required.");
		}

		String suffix =
			extension.indexOf('.') == -1 ? "." + extension : extension;
		return replacePackageToDirectory(fqcn) + suffix;
	}

	/**
	 * リソースをストリームで返す。
	 * 
	 * <p>
	 * getResourceAsStreamFromPackage(&quot;aa.bbb.Ccc&quot;,
	 * &quot;xml&quot;)であればaa/bbb/Ccc.xmlをストリームで返す。
	 * </p>
	 * 
	 * @param fqcn
	 *            「.」区切りの文字列(完全修飾名など)
	 * @param extension
	 *            拡張子
	 * @return リソース
	 */
	public static InputStream getResourceAsStreamFromPackage(String fqcn,
			String extension) {
		return getResourceAsStream(toFilePath(fqcn, extension));
	}

	/**
	 * リソースのURIを返す。
	 * 
	 * @param pathName
	 *            パス
	 * @return リソースのURI
	 */
	public static URI getURI(String pathName) {
		URL url =
			Thread
				.currentThread()
				.getContextClassLoader()
				.getResource(pathName);
		if (url == null) {
			throw new TestDataFileNotFoundException(pathName + " is not found.");
		}
		try {
			return url.toURI();
		} catch (URISyntaxException e) {
			throw new DbUnitNGRuntimeException(e);
		}
	}
}
