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

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Locale;

import junit.framework.TestCase;
import woolpack.locale.BranchByLocaleValidator;
import woolpack.test.TestUtils;
import woolpack.utils.SwitchBuilder;
import woolpack.validator.BranchByIdValidator;
import woolpack.validator.BranchByNameIfExistsValidator;
import woolpack.validator.BranchByNameValidator;
import woolpack.validator.CountValidator;
import woolpack.validator.DefaultValueValidator;
import woolpack.validator.DelegationValidator;
import woolpack.validator.DumpValidator;
import woolpack.validator.EqualsValidator;
import woolpack.validator.FormatValidator;
import woolpack.validator.IfNotValidator;
import woolpack.validator.IfValidator;
import woolpack.validator.MaxLengthValidator;
import woolpack.validator.MaxValidator;
import woolpack.validator.MessageValidator;
import woolpack.validator.MinLengthValidator;
import woolpack.validator.MinValidator;
import woolpack.validator.NotValidator;
import woolpack.validator.ParseValidator;
import woolpack.validator.RegExpIdValidator;
import woolpack.validator.RegExpValidator;
import woolpack.validator.RetainNamesValidator;
import woolpack.validator.SerialValidator;
import woolpack.validator.TmpIndexValidator;
import woolpack.validator.TmpKeyValidator;
import woolpack.validator.ValidNamesValidator;
import woolpack.validator.ValidValuesValidator;
import woolpack.validator.ValidatorConstants;
import woolpack.validator.ValidatorExpression;
import woolpack.validator.ValueLoopValidator;
import woolpack.visitor.Visitor;

public class MessageConstantsTest extends TestCase {

	private void scenario(final Object expression, final Object expected) {
		final Visitor visitor = new Visitor();
		visitor.setMap(MessageConstants.MAP);
		visitor.setContext(new ArrayList<String>());
		visitor.visit(expression);
		assertTrue(TestUtils.equals(expected, visitor.getContext()));
	}

	private void scenarioEmpty(final ValidatorExpression expression) {
		scenario(expression, Collections.EMPTY_LIST);
	}

	public void testBranchByIdValidator() {
		scenario(new BranchByIdValidator(
				new SwitchBuilder<String, ValidatorExpression>().put("id0",
						new MessageValidator("message0")).put("id1",
						new MessageValidator("message1")).get(
						new MessageValidator("message2"))), Arrays.asList(
				"message0", "message1", "message2"));
	}

	public void testBranchByNameIfExistsValidator() {
		scenario(new BranchByNameIfExistsValidator(
				new SwitchBuilder<String, ValidatorExpression>().put("id0",
						new MessageValidator("message0")).put("id1",
						new MessageValidator("message1")).get(
						new MessageValidator("message2"))), Arrays.asList(
				"message0", "message1", "message2"));
	}

	public void testBranchByNameValidator() {
		scenario(new BranchByNameValidator(
				new SwitchBuilder<String, ValidatorExpression>().put("id0",
						new MessageValidator("message0")).put("id1",
						new MessageValidator("message1")).get(
						new MessageValidator("message2"))), Arrays.asList(
				"message0", "message1", "message2"));
	}

	public void testCountValidator() {
		scenario(new CountValidator(new MessageValidator("message0")), Arrays
				.asList("message0"));
	}

	public void testDefaultValueValidator1() {
		scenarioEmpty(new DefaultValueValidator("message0"));
	}

	public void testDefaultValueValidator2() {
		scenario(new DefaultValueValidator(new MessageValidator("message0")),
				Arrays.asList("message0"));
	}

	public void testDelegationValidator() {
		scenario(new DelegationValidator(new MessageValidator("message0")),
				Arrays.asList("message0"));
	}

	public void testDumpValidator() {
		scenario(new DumpValidator(new MessageValidator("message0")), Arrays
				.asList("message0"));
	}

	public void testEqualsValidator1() {
		scenarioEmpty(new EqualsValidator("message0"));
	}

	public void testEqualsValidator2() {
		scenario(new EqualsValidator(new MessageValidator("message0")), Arrays
				.asList("message0"));
	}

	public void testFormatValidator() {
		scenarioEmpty(new FormatValidator(new DecimalFormat()));
	}

	public void testIfNotValidator() {
		scenario(new IfNotValidator(new MessageValidator("message0"),
				new MessageValidator("message1")), new HashSet<String>(Arrays
				.asList("message0", "message1")));
	}

	public void testIfValidator() {
		scenario(new IfValidator(new MessageValidator("message0"),
				new MessageValidator("message1"), new MessageValidator(
						"message2")), Collections.unmodifiableCollection(Arrays
				.asList("message0", "message1", "message2")));
	}

	public void testMaxLengthValidator() {
		scenarioEmpty(new MaxLengthValidator(1));
	}

	public void testMaxValidator() {
		scenarioEmpty(new MaxValidator(1));
	}

	public void testMessageValidator() {
		scenario(new MessageValidator("message0"), Arrays.asList("message0"));
	}

	public void testMinLengthValidator() {
		scenarioEmpty(new MinLengthValidator(1));
	}

	public void testMinValidator() {
		scenarioEmpty(new MinValidator(1));
	}

	public void testNotValidator() {
		scenario(new NotValidator(new MessageValidator("message0")), Arrays
				.asList("message0"));
	}

	public void testParseValidator() {
		scenarioEmpty(new ParseValidator(new DecimalFormat()));
	}

	public void testRegExpIdValidator() {
		scenarioEmpty(new RegExpIdValidator(".*"));
	}

	public void testRegExpValidator() {
		scenarioEmpty(new RegExpValidator(".*"));
	}

	public void testRetainNamesValidator() {
		scenarioEmpty(new RetainNamesValidator(Arrays.asList("a")));
	}

	public void testSerialValidator() {
		scenario(new SerialValidator(new MessageValidator("message0"),
				new MessageValidator("message1")), Arrays.asList("message0",
				"message1"));
	}

	public void testTmpIndexValidator() {
		scenario(new TmpIndexValidator(1, new MessageValidator("message0")),
				Arrays.asList("message0"));
	}

	public void testTmpKeyValidator() {
		scenario(new TmpKeyValidator("key0", new MessageValidator("message0")),
				Arrays.asList("message0"));
	}

	public void testTrueValidator() {
		scenarioEmpty(ValidatorConstants.TRUE);
	}

	public void testFalseValidator() {
		scenarioEmpty(ValidatorConstants.FALSE);
	}

	public void testRequiredValidator() {
		scenarioEmpty(ValidatorConstants.REQUIRED);
	}

	public void testValidNamesValidator() {
		scenarioEmpty(new ValidNamesValidator(Arrays.asList("message0")));
	}

	public void testValidValuesValidator() {
		scenarioEmpty(new ValidValuesValidator(Arrays.asList("message0")));
	}

	public void testValueLoopValidator() {
		scenario(new ValueLoopValidator(new MessageValidator("message0")),
				Arrays.asList("message0"));
	}

	public void testBranchByLocaleValidator() {
		scenario(new BranchByLocaleValidator(
				new SwitchBuilder<Locale, ValidatorExpression>().put(
						Locale.JAPANESE, new MessageValidator("message0")).put(
						Locale.ENGLISH, new MessageValidator("message1")).get(
						new MessageValidator("message2")),
				new ThreadLocal<Locale>()), Arrays.asList("message0",
				"message1", "message2"));
	}
}
