package gov.va.med.esr.voa.validator;

import gov.va.med.esr.common.model.lookup.AssociationType;
import gov.va.med.esr.common.model.lookup.Relationship;
import gov.va.med.esr.voa.common.ErrorCode;
import gov.va.med.esr.voa.webservice.AssociationInfo;
import gov.va.med.esr.voa.webservice.BaseAddressInfo;
import gov.va.med.esr.voa.webservice.ObjectFactory;

import org.springframework.validation.BindException;

public class AssociationInfoValidatorTest extends VoaCommonTestCase {

	private AssociationInfoValidator validator;

	private AssociationInfo associationInfo;

	@Override
	public void onSetUpInTransaction() throws Exception {
		super.onSetUpInTransaction();
		validator = new AssociationInfoValidator();
		validator.setLookupService(getLookupService());

		ObjectFactory factory = new ObjectFactory();
		associationInfo = factory.createAssociationInfo();

		associationInfo.setFamilyName("test");
		associationInfo.setGivenName("test");
		associationInfo.setPrimaryPhone("2141231234");
		associationInfo.setAlternatePhone("1234567890");
		associationInfo.setRelationship(Relationship.CODE_BROTHER.getCode());

		associationInfo.setContactType(AssociationType.CODE_EMERGENCY_CONTACT
				.getCode());

		BaseAddressInfo baseAddressInfo = factory.createBaseAddressInfo();
		associationInfo.setAddress(baseAddressInfo);

		baseAddressInfo.setLine1("line1");
		baseAddressInfo.setLine2("line2");
		baseAddressInfo.setLine3("line3");
		baseAddressInfo.setCity("Dallas");
		baseAddressInfo.setZipCode("75024");
		baseAddressInfo.setState("TX");
		baseAddressInfo.setCountry("USA");
	}

	@Override
	public void onTearDownInTransaction() {
		validator = null;
		associationInfo = null;
		super.onTearDownInTransaction();
	}

	public void testAssociationInfo() throws Exception {
		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);

		assertFalse(errors.hasErrors());
	}

	public void testDependent() throws Exception {
		associationInfo.setContactType(AssociationType.CODE_PRIMARY_NEXT_OF_KIN
				.getCode());

		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);

		assertFalse(errors.hasErrors());
	}

	public void testNoFamilyName() throws Exception {
		associationInfo.setContactType(AssociationType.CODE_PRIMARY_NEXT_OF_KIN
				.getCode());
		associationInfo.setFamilyName(null);

		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 1);
	}

	public void testNoGivenName() throws Exception {
		associationInfo.setContactType(AssociationType.CODE_PRIMARY_NEXT_OF_KIN
				.getCode());
		associationInfo.setGivenName(null);

		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 1);
	}

	public void testAddreeLine() throws Exception {
		associationInfo.setContactType(AssociationType.CODE_PRIMARY_NEXT_OF_KIN
				.getCode());
		ObjectFactory factory = new ObjectFactory();
		BaseAddressInfo baseAddressInfo = factory.createBaseAddressInfo();
		associationInfo.setAddress(baseAddressInfo);

		baseAddressInfo.setLine1("12344567890123456789012345678901234567890");
		baseAddressInfo.setCity("Dallas");
		baseAddressInfo.setZipCode("75024");
		baseAddressInfo.setState("TX");
		baseAddressInfo.setCountry("USA");

		associationInfo.setAddress(baseAddressInfo);
		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 1);
	}

	public void testCity() throws Exception {
		associationInfo.setContactType(AssociationType.CODE_PRIMARY_NEXT_OF_KIN
				.getCode());
		ObjectFactory factory = new ObjectFactory();
		BaseAddressInfo baseAddressInfo = factory.createBaseAddressInfo();
		associationInfo.setAddress(baseAddressInfo);

		baseAddressInfo.setLine1("12344567890123456789");
		baseAddressInfo.setCity("Dallas - 123456789012345678901234567890");
		baseAddressInfo.setZipCode("75024");
		baseAddressInfo.setState("TX");
		baseAddressInfo.setCountry("USA");

		associationInfo.setAddress(baseAddressInfo);
		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 1);
	}

	public void testPrimPhone() throws Exception {
		associationInfo.setContactType(AssociationType.CODE_PRIMARY_NEXT_OF_KIN
				.getCode());
		associationInfo.setPrimaryPhone("123");
		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 1);
	}

	public void testCellPhone() throws Exception {
		associationInfo.setContactType(AssociationType.CODE_PRIMARY_NEXT_OF_KIN
				.getCode());
		associationInfo.setAlternatePhone("123");
		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 1);
	}

	public void testRelationship() throws Exception {
		associationInfo.setContactType(AssociationType.CODE_PRIMARY_NEXT_OF_KIN
				.getCode());
		associationInfo.setRelationship(Relationship.CODE_BROTHER.getCode());
		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 0);

		associationInfo.setRelationship("myTestsRelationship");
		errors = new BindException(associationInfo, "associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 0);

		associationInfo.setRelationship("my1234testsrelationship");
		errors = new BindException(associationInfo, "associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 0);

		associationInfo.setRelationship("my space");
		errors = new BindException(associationInfo, "associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 1);

		associationInfo.setRelationship("my#@$%$chars");
		errors = new BindException(associationInfo, "associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 1);
	}

	public void testEmergencyRelationship() throws Exception {
		associationInfo.setContactType(AssociationType.CODE_EMERGENCY_CONTACT
				.getCode());
		associationInfo.setRelationship(Relationship.CODE_BROTHER.getCode());
		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 0);

		associationInfo.setRelationship("myTestsRelationship");
		errors = new BindException(associationInfo, "associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 0);

		associationInfo.setRelationship("my1234testsrelationship");
		errors = new BindException(associationInfo, "associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 0);

		associationInfo.setRelationship("my space");
		errors = new BindException(associationInfo, "associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 1);

		associationInfo.setRelationship("my#@$%$chars");
		errors = new BindException(associationInfo, "associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 1);
	}

	public void testInvalidRelationship() throws Exception {
		associationInfo.setContactType(AssociationType.CODE_PRIMARY_NEXT_OF_KIN
				.getCode());
		associationInfo.setRelationship("0000AnyText");
		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);

		assertEquals(errors.getErrorCount(), 0);
	}

	public void testAlternatePhone() throws Exception {
		associationInfo.setAlternatePhone("12312312341234");
		BindException errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);
		
		assertEquals(errors.getErrorCount(), 0);
		
		associationInfo.setAlternatePhone("12312312341234xxxx");
		errors = new BindException(associationInfo,
				"associationInfo");
		validator.validate(associationInfo, errors);
		
		boolean has_VOA_0057 = this.contain(errors, ErrorCode.VOA_0057);
		assertTrue(has_VOA_0057);
	}
	
}
