/*
 * 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.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
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 testCache() {
		final List<String> list = new ArrayList<String>();
		final Fn<ConfigContext, Void, RuntimeException> fn = ConfigUtils.cache(FnUtils.recode(
				ConfigUtils.setConfig(FnUtils.fix(new HashMap<String, Object>())),
				"id", list));
		final ConfigContext c = new SimpleConfigContext();
		fn.exec(c);
		final Map<String, Object> map = c.getConfig();
		assertEquals(1, list.size());
		c.setConfig(null);
		fn.exec(c);
		assertEquals(map, c.getConfig());
	}
	
	public void testConfigEL() {
		final ConfigContext context = new SimpleConfigContext();
		final Map<String, Object> map = new HashMap<String, Object>();
		assertTrue(ConfigUtils.CONFIG_EL.setValue(context, map));
		assertSame(map, ConfigUtils.CONFIG_EL.getValue(context));
	}
	
	public void testPutResourceBundle() {
		final ConfigContext context = new SimpleConfigContext();
		context.setConfig(new HashMap<String, Object>());
		
		ConfigUtils.putResourceBundle(FnUtils.fix(
				new ListResourceBundle(){
					private final Object[][] contents = {
							{"key0", "value0"},
							{"key1", "value1"},
					};
					@Override
					protected Object[][] getContents() {
						return contents;
					}
				}
			)).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, RuntimeException> fn = ConfigUtils.resourceBundleFactory(
				"woolpack.config.ResourceBundleFactoryTest", threadLocal);
		
		threadLocal.set(Locale.JAPANESE);
		assertEquals("value_ja0", fn.exec(null).getString("key0"));
		
		threadLocal.set(Locale.ENGLISH);
		assertEquals("value_en0", fn.exec(null).getString("key0"));
		
		threadLocal.set(null);
		assertEquals(
				Locale.getDefault().equals(Locale.JAPAN) ? "value_ja0"
				: Locale.getDefault().equals(Locale.ENGLISH) ? "value_en0" : "value0",
				fn.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 ConfigContext context = new SimpleConfigContext();
		context.setConfig(map);
		
		ConfigUtils.toLinkedHashMap("optionList0", "valueList0", "labelList0", ", ")
		.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 ConfigContext context = new SimpleConfigContext();
		context.setConfig(map);

		try {
			ConfigUtils.toLinkedHashMap("optionList0", "valueList0", "labelList0", ", ").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 ConfigContext context = new SimpleConfigContext();
		context.setConfig(map);
		
		ConfigUtils.toLinkedHashMap("valueList0", "valueList0", "valueList0", ", ")
		.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());
	}
}
