/*
 * 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.config;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.ListResourceBundle;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

import junit.framework.TestCase;
import woolpack.fn.Fn;
import woolpack.fn.FnUtils;
import woolpack.utils.Utils;

public class ConfigUtilsTest extends TestCase {
	
	public void testConfigEL() {
		final ConfigContext context = new SimpleConfigContext();
		final Map<String, Object> map = new HashMap<String, Object>();
		ConfigUtils.CONFIG_EL.setValue(context, map);
		assertSame(map, ConfigUtils.CONFIG_EL.getValue(context));
	}
	
	public void testPutResourceBundle() {
		final Fn<ConfigContext, Void> expression =
			ConfigUtils.putResourceBundle(FnUtils.fix(
					new ListResourceBundle(){
						private final Object[][] contents = {
								{"key0", "value0"},
								{"key1", "value1"},
						};
						@Override
						protected Object[][] getContents() {
							return contents;
						}
					}
				));
		final ConfigContext context = new SimpleConfigContext();
		context.setConfig(new HashMap<String, Object>());
		expression.exec(context);
		assertEquals(Utils.map("key0", "value0").map("key1", "value1"), context.getConfig());
	}

	public void testResourceBundleFactory() {
		final ThreadLocal<Locale> threadLocal = new ThreadLocal<Locale>();
		final Fn<Object, ResourceBundle> expression = ConfigUtils.resourceBundleFactory(
				"woolpack.config.ResourceBundleFactoryTest", threadLocal);
		
		threadLocal.set(Locale.JAPANESE);
		assertEquals("value_ja0", expression.exec(null).getString("key0"));
		
		threadLocal.set(Locale.ENGLISH);
		assertEquals("value_en0", expression.exec(null).getString("key0"));
		
		threadLocal.set(null);
		assertEquals(
				Locale.getDefault().equals(Locale.JAPAN) ? "value_ja0"
				: Locale.getDefault().equals(Locale.ENGLISH) ? "value_en0" : "value0",
				expression.exec(null).getString("key0"));
	}

	public void testToLinkedHashMap0() {
		final Map<String, Object> map = new HashMap<String, Object>();
		map.put("valueList0", "value0, value1, value2");
		map.put("labelList0", "label0, label1, label2");

		final Fn<ConfigContext, Void> expression =
			ConfigUtils.toLinkedHashMap("optionList0", "valueList0", "labelList0", ", ");
		final ConfigContext context = new SimpleConfigContext();
		context.setConfig(map);
		expression.exec(context);

		final Map<String, String> expected = new LinkedHashMap<String, String>();
		expected.put("value0", "label0");
		expected.put("value1", "label1");
		expected.put("value2", "label2");
		assertEquals(expected, context.getConfig().get("optionList0"));
	}

	public void testToLinkedHashMapUnmatchLength() {
		final Map<String, Object> map = new HashMap<String, Object>();
		map.put("valueList0", "value0, value1, value2, value3");
		map.put("labelList0", "label0, label1, label2");

		final Fn<ConfigContext, Void> expression =
			ConfigUtils.toLinkedHashMap("optionList0", "valueList0", "labelList0", ", ");
		final ConfigContext context = new SimpleConfigContext();
		context.setConfig(map);

		try {
			expression.exec(context);
			fail();
		} catch (final ArrayIndexOutOfBoundsException expected) {
		}
	}

	public void testToLinkedHashMapSameValueLabel() {
		final Map<String, Object> map = new HashMap<String, Object>();
		map.put("valueList0", "value0, value1, value2");

		final Fn<ConfigContext, Void> expression =
			ConfigUtils.toLinkedHashMap("valueList0", "valueList0", "valueList0", ", ");
		final ConfigContext context = new SimpleConfigContext();
		context.setConfig(map);
		expression.exec(context);

		final Map<String, String> expected = new LinkedHashMap<String, String>();
		expected.put("value0", "value0");
		expected.put("value1", "value1");
		expected.put("value2", "value2");
		assertEquals(expected, context.getConfig().get("valueList0"));
	}

	public void testAccessor() {
		final SimpleConfigContext context = new SimpleConfigContext();
		assertNull(ConfigUtils.GET_CONFIG.exec(context));
		context.setConfig(new HashMap<String, Object>());
		
		assertSame(context.getConfig(), ConfigUtils.GET_CONFIG.exec(context));
		assertSame(context.getConfig(), ConfigUtils.CONFIG_EL.getValue(context));
	}
	
	public void testSetConfig() {
		final Map<String, Object> config = new HashMap<String, Object>();
		final SimpleConfigContext context = new SimpleConfigContext();
		assertNull(ConfigUtils.setConfig(FnUtils.fix(config)).exec(context));
		assertSame(config, context.getConfig());
	}
}
