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

import java.util.List;

import gov.va.med.esr.common.model.lookup.AddressType;
import gov.va.med.esr.common.model.lookup.EthnicityType;
import gov.va.med.esr.common.model.lookup.MaritalStatus;
import gov.va.med.esr.common.model.lookup.PhoneType;
import gov.va.med.esr.common.model.lookup.RaceType;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.util.AbstractCommonTestCase;
import gov.va.med.esr.voa.webservice.AddressCollection;
import gov.va.med.esr.voa.webservice.AddressInfo;
import gov.va.med.esr.voa.webservice.ContactInfo;
import gov.va.med.esr.voa.webservice.DemographicInfo;
import gov.va.med.esr.voa.webservice.EmailCollection;
import gov.va.med.esr.voa.webservice.EmailInfo;
import gov.va.med.esr.voa.webservice.ObjectFactory;
import gov.va.med.esr.voa.webservice.PhoneCollection;
import gov.va.med.esr.voa.webservice.PhoneInfo;
import gov.va.med.esr.voa.webservice.RaceCollection;

import org.springframework.validation.BindException;

public class DemographicInfoValidatorTest extends AbstractCommonTestCase {

	private DemographicInfoValidator validator;

	private DemographicInfo demographicInfo;

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

		ObjectFactory factory = new ObjectFactory();
		demographicInfo = factory.createDemographicInfo();
		demographicInfo.setMaritalStatus(MaritalStatus.CODE_MARRIED.getCode());
		demographicInfo.setPreferredFacility(VAFacility.CODE_HEC.getCode());
		demographicInfo.setEthnicity(EthnicityType.CODE_HISPANIC.getCode());
		RaceCollection raceCollection = factory.createRaceCollection();
		raceCollection.getRace().add(
				RaceType.CODE_AMERICAN_INDIAN_ALASKA.getCode());
		demographicInfo.setRaces(raceCollection);
		demographicInfo.setReligion("AGN"); // Agnostic

		ContactInfo contactInfo = factory.createContactInfo();
		demographicInfo.setContactInfo(contactInfo);

		AddressCollection addressCollection = factory.createAddressCollection();
		AddressInfo addressInfo = factory.createAddressInfo();
		addressCollection.getAddress().add(addressInfo);
		contactInfo.setAddresses(addressCollection);
		addressInfo.setLine1("Address Line 1");
		addressInfo.setLine2("Address Line 2");
		addressInfo.setLine3("Address Line 3");
		addressInfo.setCity("Dallas");
		addressInfo.setState("TX");
		addressInfo.setCountry("USA");
		addressInfo.setZipCode("75024");
		addressInfo.setAddressTypeCode(AddressType.CODE_PERMANENT_ADDRESS
				.getCode());

		EmailCollection emailCollection = factory.createEmailCollection();
		EmailInfo emailInfo = factory.createEmailInfo();
		emailCollection.getEmail().add(emailInfo);
		contactInfo.setEmails(emailCollection);
		emailInfo.setAddress("test123@test.com");

		PhoneCollection phoneCollection = factory.createPhoneCollection();
		contactInfo.setPhones(phoneCollection);
		PhoneInfo phoneInfo1 = factory.createPhoneInfo();
		phoneCollection.getPhone().add(phoneInfo1);
		phoneInfo1.setPhoneNumber("2142221234");
		phoneInfo1.setType(PhoneType.CODE_HOME.getCode());

		PhoneInfo phoneInfo2 = factory.createPhoneInfo();
		phoneCollection.getPhone().add(phoneInfo2);
		phoneInfo2.setPhoneNumber("1234567890");
		phoneInfo2.setType(PhoneType.CODE_MOBILE.getCode());
	}

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

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

		assertFalse(errors.hasErrors());
	}

	public void testInvalidMaritalStatus() throws Exception {
		BindException errors = new BindException(demographicInfo,
				"demographicInfo");
		demographicInfo.setMaritalStatus("invalidStatusCode");

		validator.validate(demographicInfo, errors);

		assertTrue(errors.hasErrors());
	}

	public void testInvalidFacility() throws Exception {
		BindException errors = new BindException(demographicInfo,
				"demographicInfo");
		demographicInfo.setPreferredFacility("invalidFacility");

		validator.validate(demographicInfo, errors);

		assertTrue(errors.hasErrors());
	}

	public void testInvalidEthnicity() throws Exception {
		BindException errors = new BindException(demographicInfo,
				"demographicInfo");
		demographicInfo.setEthnicity("invalid");

		validator.validate(demographicInfo, errors);

		assertTrue(errors.hasErrors());
	}

	public void testInvalidReligion() throws Exception {
		BindException errors = new BindException(demographicInfo,
				"demographicInfo");
		demographicInfo.setReligion("invalid");

		validator.validate(demographicInfo, errors);

		assertTrue(errors.hasErrors());
	}

	public void testInvalidAddress() throws Exception {
		BindException errors = new BindException(demographicInfo,
				"demographicInfo");
		ContactInfo contactInfo = demographicInfo.getContactInfo();
		AddressCollection addressCollection = contactInfo.getAddresses();
		List<AddressInfo> addressInfoList = addressCollection.getAddress();
		for (AddressInfo addressInfo : addressInfoList) {
			addressInfo.setLine1("1234 main");
		}

		validator.validate(demographicInfo, errors);

		assertFalse(errors.hasErrors());

		for (AddressInfo addressInfo : addressInfoList) {
			addressInfo.setLine1("");
		}

		validator.validate(demographicInfo, errors);

		assertTrue(errors.hasErrors());
	}
	
	public void testInvalidAddressCity() throws Exception {
		BindException errors = new BindException(demographicInfo,
				"demographicInfo");
		ContactInfo contactInfo = demographicInfo.getContactInfo();
		AddressCollection addressCollection = contactInfo.getAddresses();
		List<AddressInfo> addressInfoList = addressCollection.getAddress();
		for (AddressInfo addressInfo : addressInfoList) {
			addressInfo.setCity("");
		}
		
		validator.validate(demographicInfo, errors);
		assertTrue(errors.hasErrors());
	}

	public void testInvalidAddressState() throws Exception {
		BindException errors = new BindException(demographicInfo,
				"demographicInfo");
		ContactInfo contactInfo = demographicInfo.getContactInfo();
		AddressCollection addressCollection = contactInfo.getAddresses();
		List<AddressInfo> addressInfoList = addressCollection.getAddress();
		for (AddressInfo addressInfo : addressInfoList) {
			addressInfo.setState("");
		}
		
		validator.validate(demographicInfo, errors);
		assertTrue(errors.hasErrors());
	}
	
	public void testInvalidAddressState2() throws Exception {
		BindException errors = new BindException(demographicInfo,
				"demographicInfo");
		ContactInfo contactInfo = demographicInfo.getContactInfo();
		AddressCollection addressCollection = contactInfo.getAddresses();
		List<AddressInfo> addressInfoList = addressCollection.getAddress();
		for (AddressInfo addressInfo : addressInfoList) {
			addressInfo.setState("invalid");
		}
		
		validator.validate(demographicInfo, errors);
		assertTrue(errors.hasErrors());
	}
	
	public void testInvalidAddressZip() throws Exception {
		BindException errors = new BindException(demographicInfo,
				"demographicInfo");
		ContactInfo contactInfo = demographicInfo.getContactInfo();
		AddressCollection addressCollection = contactInfo.getAddresses();
		List<AddressInfo> addressInfoList = addressCollection.getAddress();
		for (AddressInfo addressInfo : addressInfoList) {
			addressInfo.setZipCode(null);
		}
		
		validator.validate(demographicInfo, errors);
		assertTrue(errors.hasErrors());
	}
	
	public void testInvalidAddressZip2() throws Exception {
		BindException errors = new BindException(demographicInfo,
				"demographicInfo");
		ContactInfo contactInfo = demographicInfo.getContactInfo();
		AddressCollection addressCollection = contactInfo.getAddresses();
		List<AddressInfo> addressInfoList = addressCollection.getAddress();
		for (AddressInfo addressInfo : addressInfoList) {
			addressInfo.setZipCode("123");
		}
		
		validator.validate(demographicInfo, errors);
		assertTrue(errors.hasErrors());
	}
	
}
