/*
 * Copyright 2006 Takahiro Nakamura.
 *
 * 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 woolpack.utils.fn;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import woolpack.fn.Fn;
import woolpack.utils.PropertyUtils;
import woolpack.utils.Utils;

/**
 * {@link Utils}と{@link PropertyUtils}の各メソッドを{@link Fn}でラップした機能のユーティリティです。
 * @author nakamura
 *
 */
public final class UtilsFnUtils {
	
	/**
	 * @see Utils#arrayToList(Object)
	 */
	public static final Fn<Object, List<Object>, RuntimeException> ARRAY_TO_LIST = new Fn<Object, List<Object>, RuntimeException>() {
		public List<Object> exec(final Object c) throws RuntimeException {
			return Utils.arrayToList(c);
		}
	};
	
	/**
	 * @see Utils#toIterable(Object)
	 */
	public static final Fn<Object, Iterable<?>, RuntimeException> TO_ITERABLE = new Fn<Object, Iterable<?>, RuntimeException>() {
		public Iterable<?> exec(final Object c) throws RuntimeException {
			return Utils.toIterable(c);
		}
	};
	
	/**
	 * @see Utils#toCollection(Object)
	 */
	public static final Fn<Object, Collection<?>, RuntimeException> TO_COLLECTION = new Fn<Object, Collection<?>, RuntimeException>() {
		public Collection<?> exec(final Object c) throws RuntimeException {
			return Utils.toCollection(c);
		}
	};
	
	/**
	 * @see Utils#toList(Object)
	 */
	public static final Fn<Object, List<?>, RuntimeException> TO_LIST = new Fn<Object, List<?>, RuntimeException>() {
		public List<?> exec(final Object c) throws RuntimeException {
			return Utils.toList(c);
		}
	};
	
	/**
	 * @see Utils#toMessageList(Throwable)
	 */
	public static final Fn<Throwable, List<String>, RuntimeException> TO_MESSAGE_LIST = new Fn<Throwable, List<String>, RuntimeException>() {
		public List<String> exec(final Throwable c) throws RuntimeException {
			return Utils.toMessageList(c);
		}
	};
	
	/**
	 * @see PropertyUtils#getGuessingIterable(String)
	 */
	public static final Fn<String, Iterable<String>, RuntimeException> PROPERTY_GUESSING_FACTORY =
		getPropertyGuessingIterable('_');
	
	private UtilsFnUtils() {
	}

	/**
	 * 
	 * @param <K>
	 * @param <V>
	 * @return 関数。
	 * @see Utils#inverseMap(Map)
	 */
	public static <K, V> Fn<Map<K, V>, Map<V, K>, RuntimeException> inverseMap() {
		return new Fn<Map<K, V>, Map<V, K>, RuntimeException>() {
			public Map<V, K> exec(final Map<K, V> c) throws RuntimeException {
				return Utils.inverseMap(c);
			}
		};
	}

	/**
	 * 
	 * @param <K>
	 * @param <V>
	 * @return 関数。
	 * @see Utils#injectiveMap(Map)
	 */
	public static <K, V> Fn<Map<K, V>, Map<K, V>, RuntimeException> injectiveMap() {
		return new Fn<Map<K, V>, Map<K, V>, RuntimeException>() {
			public Map<K, V> exec(final Map<K, V> c) throws RuntimeException {
				return Utils.injectiveMap(c);
			}
		};
	}

	/**
	 * 
	 * @param <K>
	 * @param <V>
	 * @return 関数。
	 * @see Utils#unoverwritableMap(Map)
	 */
	public static <K, V> Fn<Map<K, V>, Map<K, V>, RuntimeException> unoverwritableMap() {
		return new Fn<Map<K, V>, Map<K, V>, RuntimeException>() {
			public Map<K, V> exec(final Map<K, V> c) throws RuntimeException {
				return Utils.unoverwritableMap(c);
			}
		};
	}

	/**
	 * 
	 * @param <K>
	 * @param <V>
	 * @return 関数。
	 * @see Utils#notNullMap(Map)
	 */
	public static <K, V> Fn<Map<K, V>, Map<K, V>, RuntimeException> notNullMap() {
		return new Fn<Map<K, V>, Map<K, V>, RuntimeException>() {
			public Map<K, V> exec(final Map<K, V> c) throws RuntimeException {
				return Utils.notNullMap(c);
			}
		};
	}

	/**
	 * 
	 * @param <V>
	 * @return 関数。
	 * @see Utils#keyNotEmptyMap(Map)
	 */
	public static <V> Fn<Map<String, V>, Map<String, V>, RuntimeException> keyNotEmptyMap() {
		return new Fn<Map<String, V>, Map<String, V>, RuntimeException>() {
			public Map<String, V> exec(final Map<String, V> c) throws RuntimeException {
				return Utils.keyNotEmptyMap(c);
			}
		};
	}

	/**
	 * 
	 * @param <V>
	 * @return 関数。
	 * @see Utils#similarKeyMap(Map)
	 */
	public static <V> Fn<Map<String, V>, Map<String, V>, RuntimeException> similarKeyMap() {
		return new Fn<Map<String, V>, Map<String, V>, RuntimeException>() {
			public Map<String, V> exec(final Map<String, V> c) throws RuntimeException {
				return Utils.similarKeyMap(c);
			}
		};
	}
	
	/**
	 * 
	 * @param <E>
	 * @return 関数。
	 * @see Utils#unmodifiableIterable(Iterable)
	 */
	public static <E> Fn<Iterable<E>, Iterable<E>, RuntimeException> unmodifiableIterable() {
		return new Fn<Iterable<E>, Iterable<E>, RuntimeException>() {
			public Iterable<E> exec(final Iterable<E> c) throws RuntimeException {
				return Utils.unmodifiableIterable(c);
			}
		};
	}
	
	/**
	 * 
	 * @param separator
	 * @return 関数。
	 * @see PropertyUtils#getGuessingIterable(String, char)
	 */
	public static Fn<String, Iterable<String>, RuntimeException> getPropertyGuessingIterable(final char separator) {
		return new Fn<String, Iterable<String>, RuntimeException>() {
			public Iterable<String> exec(final String c) throws RuntimeException {
				return PropertyUtils.getGuessingIterable(c, separator);
			}
		};
	}
}
