package gov.va.med.esr.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import gov.va.med.esr.common.infra.ImpreciseDate;
import gov.va.med.esr.common.model.CommonEntityKeyFactory;
import gov.va.med.esr.common.model.lookup.Gender;
import gov.va.med.esr.common.model.lookup.NameType;
import gov.va.med.esr.common.model.lookup.SSNType;
import gov.va.med.esr.common.model.messaging.SiteIdentity;
import gov.va.med.esr.common.model.party.Address;
import gov.va.med.esr.common.model.person.BirthRecord;
import gov.va.med.esr.common.model.person.Name;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.person.SSN;
import gov.va.med.esr.common.model.person.id.VPIDEntityKey;
import gov.va.med.esr.common.util.AbstractServiceTestCase;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.util.StringUtils;
import gov.va.med.person.idmgmt.VPID;
import gov.va.med.ps.model.PersonVPID;

/**
 * Test some PSDelegate service API's.
 * 
 * @author Andrew Pach
 */
public class PSDelegateServiceTest extends AbstractServiceTestCase {

	private String firstName = "John";
	private String lastName = "ESR-TESTFEB";
	private String middleName = "M";
	private String addLine1 = "675 Less st";
	private String addLine2 = "#123";
	private String addCity = "Ashburn";
	private String addState = "VA";
	private String addZip = "20148";
	private String homePhone = "703-324-1234";
	private String ssn = "972712100";
	private String dob = "19700101";
	private String gender = "M";

	// The number of threads (i.e. simulatenous calls to PSIM) to use
	public static final int NUM_THREADS = 500;

	// Approximate number of seconds until we timeout the JUnit. Make sure this
	// value is high enough
	// to let the number of threads above finish successfully.
	public static final int TIMEOUT_SECS = 300;

	// The approximate number of seconds to wait before displaying additional
	// debugging output
	// regarding the threads
	public static final int DEBUG_INFO_SECS = 5;

	// Number of milliseconds to wait in between starting threads
	public static final int THREAD_START_DELAY_MILLIS = 100;


	private PersonIdentityTraits createTraitsForDeprecatedICNs()
			throws Exception {

		PersonIdentityTraits traits = new PersonIdentityTraits();
		VPIDEntityKey key = CommonEntityKeyFactory
				.createVPIDEntityKey("0000001001179466V415562000000");
		traits.setVpid(key);

		Name lName = new Name();
		String prefixName = "";
		lName.setGivenName(firstName);
		lName.setMiddleName(middleName);
		lName.setFamilyName(lastName);
		// lName.setType();
		// lName.setType(gov.va.med.esr.common.model.lookup.NameType.LEGAL_NAME.getCode());
		Set names = new HashSet();
		names.add(lName);
		traits.setNames(names);

		BirthRecord br = new BirthRecord();
		br.setBirthDate(new ImpreciseDate(dob));
		traits.setBirthRecord(br);
		Gender gender = getLookupService().getGenderByCode("M");
		traits.setGender(gender);

		Address permAddress = new Address();
		permAddress.setLine1(addLine1);
		permAddress.setLine2(addLine2);
		permAddress.setLine3("");
		permAddress.setCity(addCity);
		permAddress.setZipCode("20148");
		permAddress.setZipPlus4("1234");
		permAddress.setPostalCode(addZip);
		permAddress.setState(addState);
		permAddress.setCountry("USA");
		permAddress.setPhoneNumber(homePhone);
		permAddress.setType(getLookupService().getAddressTypeByCode("P"));

		Set addresses = new HashSet();
		addresses.add(permAddress);
		// traits.addAddress(permAddress);
		traits.setAddresses(addresses);

		SSN ssN = new SSN();
		ssN.setSsnText(ssn);
		traits.setSsn(ssN);
		return traits;
	}

	private PersonIdentityTraits createTraits() throws Exception {

		PersonIdentityTraits traits = new PersonIdentityTraits();

		Name lName = new Name();
		String prefixName = "";
		lName.setGivenName(firstName);
		lName.setMiddleName(middleName);
		lName.setFamilyName(lastName);
		// lName.setType();
		// lName.setType(gov.va.med.esr.common.model.lookup.NameType.LEGAL_NAME.getCode());
		Set names = new HashSet();
		names.add(lName);
		traits.setNames(names);

		BirthRecord br = new BirthRecord();
		br.setBirthDate(new ImpreciseDate(dob));
		traits.setBirthRecord(br);
		Gender gender = getLookupService().getGenderByCode("M");
		traits.setGender(gender);

		Address permAddress = new Address();
		permAddress.setLine1(addLine1);
		permAddress.setLine2(addLine2);
		permAddress.setLine3("");
		permAddress.setCity(addCity);
		permAddress.setZipCode("20148");
		permAddress.setZipPlus4("1234");
		permAddress.setPostalCode(addZip);
		permAddress.setState(addState);
		permAddress.setCountry("USA");
		permAddress.setPhoneNumber(homePhone);
		permAddress.setType(getLookupService().getAddressTypeByCode("P"));

		Set addresses = new HashSet();
		addresses.add(permAddress);
		// traits.addAddress(permAddress);
		traits.setAddresses(addresses);
		SSN ssN = new SSN();
		ssN.setSsnText(ssn);
		traits.setSsn(ssN);
		return traits;
	}

	private PersonIdentityTraits createTraits2() throws Exception  {
		
		PersonIdentityTraits traits = new PersonIdentityTraits();
		Name lName = new Name();

		String prefixName = "";

		lName.setGivenName("PATIENT");
		lName.setFamilyName("MANNY");
		//lName.setType();
		//lName.setType(gov.va.med.esr.common.model.lookup.NameType.LEGAL_NAME.getCode());
		HashSet names = new HashSet();
		names.add(lName);
		traits.setNames(names);
	
		BirthRecord br = new BirthRecord();
		br.setBirthDate(new ImpreciseDate("19520724"));
		traits.setBirthRecord(br);
		Gender gender = getLookupService().getGenderByCode("M");
		traits.setGender(gender);
		
		
		Address permAddress = new Address();
		permAddress.setLine1(addLine1);
		permAddress.setLine2(addLine2);
		permAddress.setLine3("");
		permAddress.setCity(addCity);
		permAddress.setZipCode("20148");
		permAddress.setZipPlus4("1234");
		permAddress.setPostalCode(addZip);
		permAddress.setState(addState);
		permAddress.setCountry("USA");
		permAddress.setPhoneNumber(homePhone);
		permAddress.setType(getLookupService().getAddressTypeByCode("P"));
		traits.addAddress(permAddress);
		
		SSN ssN = new SSN();
		ssN.setSsnText("456331987");
		traits.setSsn(ssN);
		return traits;
	}


	//CR 11776 -testing of UnattendedSearch with IdmWS
	public void testUnattendedSearchWS() throws Exception {

		Set traits = getPsDelegateService().unattendedSearch(createTraits());
		assertEquals(1, traits.size());
		assertFalse(traits.isEmpty());
		PersonIdentityTraits pit = ((PersonIdentityTraits)traits.toArray()[0]);
		assertEquals("0000001008590691V692791000000", pit.getVpid().getVPID());
		
		Name nm = (Name)pit.getNames().toArray()[0];
		assertEquals("JOHN", nm.getGivenName());
		assertEquals("ESR-TESTFEB", nm.getFamilyName());
		assertEquals("972712100", pit.getSsnText());
		
		System.out.println(traits.toString());
		System.out.println("Unattended search found this many traits: "
				+ traits.size());
	}

	public void testUnattendedSearchInvalidCombo() throws Exception {
		boolean expectedResult = false;
		try {
			getPsDelegateService().unattendedSearch(
					createSearchTraitsForInvalidSearch());
		} catch (Exception e) {
			expectedResult = true;
		}
		assertTrue(expectedResult);
	}


    //CR 11776 attended search by IdmWS
	public void testAttendedSearchWS() throws Exception {
		
		Set personTraits = getPsDelegateService().attendedSearch(createTraits2(), false); // don't enforce security in JUnit
		assertTrue(personTraits.size() == 1);
		PersonIdentityTraits pit = (PersonIdentityTraits) personTraits.toArray()[0];
		

		assertEquals("Male", pit.getGender().getName());
		assertEquals("M", pit.getGender().getCode());

		assertEquals("0000001001179498V308768000000", pit.getVpid().getVPID());
		assertEquals(false, pit.isDeprecated());
		assertEquals(false, pit.isHasPendingUpdates());

		Set names = pit.getNames();
		System.out.println(names.size());
		assertTrue(names.size() == 1);
		
		Name nm = (Name)pit.getNames().toArray()[0];
		assertEquals("MY SECOND", nm.getGivenName());
		assertEquals("RONCE", nm.getFamilyName());
		assertEquals("456331987", pit.getSsnText());
		
		assertFalse(personTraits.isEmpty());
		System.out.println("Attended search found this many PersonIdentity traits: "
				+ personTraits.size());
	}


	public void testIdentityTraitsCheck() throws Exception {
		//VPIDEntityKey key = CommonEntityKeyFactory
				//.createVPIDEntityKey(PersonVPID.DEFAULT_TESTING_VPID);
		VPIDEntityKey key =
		 CommonEntityKeyFactory.createVPIDEntityKey("1008590775V635010");
		assertTrue(key != null);
		Person person = getPersonService().getPerson(key);

		PersonIdentityTraits incomingTraits = getPsDelegateService()
				.extractIdentityTraits(person);
		PersonIdentityTraits onFileTraits = getPsDelegateService()
				.getIdentityTraits(key);
		System.out.println(onFileTraits);
		assertEquals(incomingTraits, onFileTraits);
		incomingTraits.setHasPendingUpdates(true); // no bearing on equality
		onFileTraits.setHasPendingUpdates(false); // no bearing on equality
		assertEquals(incomingTraits, onFileTraits);
	}

	
	//CR 11776 - this test should always return false since surviving traits  is returned..
	public void testDeprecatedPerson() throws Exception {

		/*
		 * deprecated ones from Lavanya 0000001001179466V415562000000
		 * 0000001001170375V094875000000 0000001001179713V288673000000
		 * 0000001001169343V134062000000 0000001008522286V412237000000
		 * 0000001008522496V535571000000 0000001008523836V480329000000
		 */

		String[] vpids = { "1001179466V415562", "1001170375V094875",
				"1001169343V134062", "1008523836V480329" };

		VPIDEntityKey key = CommonEntityKeyFactory
				.createVPIDEntityKey(vpids[0]);
		PersonIdentityTraits traits = getPsDelegateService().getIdentityTraits(
				key);
		assertEquals(false, traits.isDeprecated());

		key = CommonEntityKeyFactory.createVPIDEntityKey(vpids[1]);
		traits = getPsDelegateService().getIdentityTraits(key);
		assertEquals(false, traits.isDeprecated());

		key = CommonEntityKeyFactory.createVPIDEntityKey(vpids[2]);
		traits = getPsDelegateService().getIdentityTraits(key);
		assertEquals(false, traits.isDeprecated());

		key = CommonEntityKeyFactory.createVPIDEntityKey(vpids[3]);
		traits = getPsDelegateService().getIdentityTraits(key);
		assertEquals(false, traits.isDeprecated());

	}

	public void testCCR11403() throws Exception {
		VPIDEntityKey key = CommonEntityKeyFactory
				.createVPIDEntityKey("0000001008591040V583029000000");
		// Person person = getPersonService().getPerson(key);
		// PersonIdentityTraits incomingTraits =
		// getPsDelegateService().extractIdentityTraits(person);

		// List personIds =
		// this.getDAO().executeSQLQuery("SELECT ed.person_id FROM enrollment_determination ed WHERE NOT EXISTS (SELECT p.person_id  FROM person p, ps_person_correlation pc WHERE p.person_id = ed.person_id AND p.vpid_id = pc.person_vpid_id AND pc.system_of_interest_type_id = 139)",
		// "ALTER SESSION FORCE PARALLEL QUERY");
		// assertEquals(383, personIds.size());

		// get person traits by dnf + station number
		String dfn = "0000001008591266V400774000000";
		String stationNumber = "200ESR";
		// PersonIdentityTraits onFileTraits =
		// getPsDelegateService().getIdentityTraits(dfn, stationNumber);
		// //original
		PersonIdentityTraits onFileTraits = getPsDelegateService()
				.getIdentityTraitsWithCompositeCall(dfn, stationNumber);
		assertEquals("547638251", onFileTraits.getSsnText()); // SSN
		assertEquals(
				"1952/05/29",
				new SimpleDateFormat("yyyy/MM/dd").format(onFileTraits
						.getBirthRecord().getBirthDate().getDate())); // DOB
		assertEquals("BLUEBELL", onFileTraits.getLegalName().getFamilyName()); // family
																				// name
		assertEquals("JOSHUA", onFileTraits.getLegalName().getGivenName()); // given
																			// name
		assertEquals("F", onFileTraits.getGender().getCode()); // gender

		// testing search by vpid
		onFileTraits = getPsDelegateService().getIdentityTraits(key);
		assertEquals("222001111", onFileTraits.getSsnText()); // SSN
		assertEquals(
				"1970/01/01",
				new SimpleDateFormat("yyyy/MM/dd").format(onFileTraits
						.getBirthRecord().getBirthDate().getDate())); // DOB
		assertEquals("SVAHVPJJXOGTGT", onFileTraits.getLegalName()
				.getFamilyName()); // family name
		// assertEquals("FIRST", onFileTraits.getLegalName().getGivenName());
		// //given name
		// assertEquals("M", onFileTraits.getGender().getCode()); //gender

		// get Id State
		String idState = getPsDelegateService().getIDState(key);
		// assertEquals(idState, "P");

		// get isSystemOrHealthCareUser
		// boolean isSysOrHealthCare =
		// getPsDelegateService().isSystemOrHealthCareUser(key);
		// assertEquals(true, isSysOrHealthCare);

	}

	public void testGetIdentityTraitsWithCompositeCall()
			throws ServiceException, Exception {
		String dfn = "0000001008522565V314128000000";
		String stationNumber = "200ESR";

		PersonIdentityTraits traits = getPsDelegateService()
				.getIdentityTraitsWithCompositeCall(dfn, stationNumber);
		assertEquals(false, traits.isDeprecated());
		assertEquals(false, traits.isPendingStatus());
		System.out.println("vpid: " + traits.getVpid());
	}

	

	public void testGetIdentityTraitsWithCompositeCall2()
			throws ServiceException, Exception {
		String dfn = "100002638";
		String stationNumber = "553";

		PersonIdentityTraits traits = getPsDelegateService().getIdentityTraitsWithCompositeCall(dfn, stationNumber);
		assertEquals(false, traits.isDeprecated());
		assertEquals(false, traits.isPendingStatus());
		System.out.println("vpid: " + traits.getVpid());
	}

	
	
	
	public void testGetIdentityTraitsByVPIDWithCompositeCall()
			throws ServiceException, Exception {
		String key = "1001168528V211848";
		
		PersonIdentityTraits traits = getPsDelegateService().getIdentityTraitsWithCompositeCall(CommonEntityKeyFactory.createVPIDEntityKey(key));
		assertEquals(false, traits.isDeprecated());
		assertEquals(false, traits.isPendingStatus());
		assertEquals("Y", traits.has200ESRCorrelation());
		assertEquals("0000001001168528V211848000000", traits.getVpid().getVPID());
	}
	
	
	public void testGetIdentityTraitsByVPIDWithNonCompositeCall()
			throws ServiceException, Exception {
		String key = "1001168528V211848";
		
		PersonIdentityTraits traits = getPsDelegateService().getIdentityTraits(CommonEntityKeyFactory.createVPIDEntityKey(key));
		assertEquals(false, traits.isDeprecated());
		assertEquals(false, traits.isPendingStatus());
		assertEquals("N", traits.has200ESRCorrelation());
		assertEquals("0000001001168528V211848000000", traits.getVpid().getVPID());
		
	}
	
	
	
	// the test method is not used by ESR anymore
	/*
	 * public void testGetVPIDsBYSSNVerificationStatus() throws Exception { Set
	 * criteria = new HashSet();
	 * criteria.add(SSAVerificationStatus.NEW_RECORD.getCode());
	 * criteria.add(SSAVerificationStatus.RESEND_TO_SSA.getCode()); Set vpids =
	 * getPsDelegateService().getVPIDsBySSAVerificationStatuses(criteria);
	 * System
	 * .out.println("Retrieved this many VPIDs by SSA Verification status: " +
	 * (vpids != null ? vpids.size() : 0));
	 * 
	 * Iterator itr = vpids.iterator(); while(itr.hasNext()) {
	 * System.out.println("traits: " + getPsDelegateService().getIdentityTraits(
	 * ((VPIDEntityKey) itr.next()))); } }
	 */

	public void testGetIdentityTraitsUpdateHistory() throws Exception {
		VPIDEntityKey key = CommonEntityKeyFactory
				.createVPIDEntityKey("0000001008590775V635010000000");
		// VPIDEntityKey key =
		// CommonEntityKeyFactory.createVPIDEntityKey(PersonVPID.HARDCODED_PSIM_VPID_VALUE5);
		List items = getPsDelegateService().getIdentityTraitsUpdateHistory(key);
		Iterator itr = items != null ? items.iterator() : null;
		while (itr != null && itr.hasNext()) {
			System.out.println("Item: " + itr.next());
		}
	}

	public void testGetShortVPID() {
		String longVPID = PersonVPID.HARDCODED_PSIM_VPID_VALUE3;
		String shortVPID = VPID.getShortVPID(longVPID);
		System.out.println("Long VPID (size " + longVPID.length() + "): "
				+ longVPID);
		System.out.println("Short VPID (size " + shortVPID.length() + "): "
				+ shortVPID);
	}

	private PersonIdentityTraits createSearchTraits() throws Exception {
		PersonIdentityTraits traits = createSearchTraitsFNameLname();
		SSN ssn = new SSN();
		ssn.setType(getLookupService().getSSNTypeByCode(
				SSNType.CODE_ACTIVE.getCode()));
		ssn.setSsnText("972712100");

		traits.setSsn(ssn);
		BirthRecord birthrecord = new BirthRecord();
		birthrecord.setBirthDate(new ImpreciseDate("19700101"));
		traits.setBirthRecord(birthrecord);
		return traits;
	}

	private PersonIdentityTraits createSearchTraitsFNameLname()
			throws Exception {
		PersonIdentityTraits traits = new PersonIdentityTraits();
		Name name = new Name();
		name.setType(getLookupService().getNameTypeByCode(
				NameType.LEGAL_NAME.getCode()));
		name.setFamilyName("ESR-TESTPATIENTOR");
		name.setGivenName("TESTOR");
		traits.addName(name);
		return traits;
	}

	private PersonIdentityTraits createSearchTraitsForInvalidSearch()
			throws Exception {
		PersonIdentityTraits traits = new PersonIdentityTraits();
		SSN ssn = new SSN();
		ssn.setType(getLookupService().getSSNTypeByCode(
				SSNType.CODE_ACTIVE.getCode()));
		ssn.setSsnText("000830483");
		traits.setSsn(ssn);
		// BirthRecord birthrecord = new BirthRecord();
		// birthrecord.setBirthDate(new ImpreciseDate("4/4/1933"));
		// traits.setBirthRecord(birthrecord);
		return traits;
	}


	public void testGetMultipleIdentityTraits() throws Exception {
		Collection vpids = new ArrayList();
		vpids.add(CommonEntityKeyFactory
				.createVPIDEntityKey(PersonVPID.HARDCODED_PSIM_VPID_VALUE1));
		vpids.add(CommonEntityKeyFactory
				.createVPIDEntityKey(PersonVPID.HARDCODED_PSIM_VPID_VALUE2));
		vpids.add(CommonEntityKeyFactory
				.createVPIDEntityKey(PersonVPID.HARDCODED_PSIM_VPID_VALUE3));
		vpids.add(CommonEntityKeyFactory
				.createVPIDEntityKey(PersonVPID.HARDCODED_PSIM_VPID_VALUE4));
		vpids.add(CommonEntityKeyFactory
				.createVPIDEntityKey(PersonVPID.HARDCODED_PSIM_VPID_VALUE5));
		Map data = getPsDelegateService().getIdentityTraits(vpids);
		assertTrue(data.size() == 5);
		System.out.println("Returned data: " + data);
	}

	public void testGetPsimVpidValue() throws Exception {
		Iterator iter = PersonVPID.VALID_VPIDS.iterator();
		while (iter.hasNext()) {
			String vpidValue = (String) iter.next();
			String psimVpidValue = getPsimVpidValue(vpidValue);
			if (!psimVpidValue.equals(vpidValue)) {
				invalidVpidValue(vpidValue, psimVpidValue);
			}
			validVpidValue(vpidValue, psimVpidValue);
		}
	}

	public void testMultipleGetIdentityTraits() throws Exception {
		// Ensure we have at least one VPID value to test with
		if (PersonVPID.VALID_VPIDS.isEmpty()) {
			fail("No VPID values to test with.");
		}

		Iterator iter = null;
		ArrayList threadList = new ArrayList();

		// Spawn a bunch of threads for testing the getting of a VPID value
		for (int i = 0; i < NUM_THREADS; i++) {
			// Get the next VPID value
			if ((iter == null) || (!iter.hasNext())) {
				iter = PersonVPID.VALID_VPIDS.iterator();
			}
			String vpidValue = (String) iter.next();

			Thread vpidThread = new TestVpidThread(vpidValue,
					getPsDelegateService());
			threadList.add(vpidThread);
			vpidThread.start();
			Thread.sleep(THREAD_START_DELAY_MILLIS);
		}

		boolean finished = false;
		int timeoutCount = 0;
		int threadsNotCompleteCount = 0;
		while (!finished) {
			// Increment the timeout count in seconds
			timeoutCount++;

			threadsNotCompleteCount = 0;
			boolean threadsCompleted = true;
			for (Iterator iterator = threadList.iterator(); iterator.hasNext();) {
				TestVpidThread thread = (TestVpidThread) iterator.next();
				if (thread.isAlive()) {
					threadsCompleted = false;
					threadsNotCompleteCount++;
				}
			}

			// If all the threads are completed, then we are finished
			if (threadsCompleted) {
				finished = true;
			}

			if (!finished) {
				// Timeout the JUnit if we have waited too long
				if (timeoutCount >= TIMEOUT_SECS) {
					finished = true;
				}

				// Display summary debugging information every so often
				if (timeoutCount % DEBUG_INFO_SECS == 0) {
					displaySummaryInfo(timeoutCount, threadList.size(),
							threadsNotCompleteCount);
				}

				// Sleep for 1 second before we try again
				try {
					Thread.sleep(1000);
				} catch (Exception ex) {
					ex.printStackTrace();
				}
			}
		}

		// Display the summary information
		displaySummaryInfo(timeoutCount, threadList.size(),
				threadsNotCompleteCount);

		int validVpidValueCount = 0;
		int invalidVpidValueCount = 0;
		int timeoutVpidValueCount = 0;
		Map traitMap = new HashMap();

		// Iterate through the threads to capture the result statistics
		for (Iterator iterator = threadList.iterator(); iterator.hasNext();) {
			TestVpidThread thread = (TestVpidThread) iterator.next();
			if (thread.isAlive()) {
				// The thread timed out
				timeoutVpidValue(thread.getVpidValue());
				timeoutVpidValueCount++;
			} else {
				// The thread returned so get the traits and compare them to any
				// other thread's traits
				// that used the same VPID
				PersonIdentityTraits threadTraits = thread.getTraits();
				PersonIdentityTraits previousTraits = (PersonIdentityTraits) traitMap
						.get(threadTraits.getVpid().getVPID());
				if (previousTraits == null) {
					// This is the first thread for this VPID so store the
					// traits
					traitMap.put(threadTraits.getVpid().getVPID(), threadTraits);
					validTraits(threadTraits);
					validVpidValueCount++;
				} else {
					if ((traitsEqual(threadTraits, previousTraits))
							&& (threadTraits.getVpid().getVPID()
									.equals(previousTraits.getVpid().getVPID()))) {
						// The previous thread's traits for this VPID match the
						// current thread's traits
						validTraits(threadTraits);
						validVpidValueCount++;
					} else {
						// The previous thread's traits for this VPID DON'T
						// match the current thread's traits
						invalidTraits(threadTraits, previousTraits);
						invalidVpidValueCount++;
					}
				}
			}
		}

		displayVpidSummaryInfo(timeoutCount, validVpidValueCount,
				invalidVpidValueCount, timeoutVpidValueCount);

		if (timeoutVpidValueCount > 0) {
			fail("Timed out while waiting for threads to complete.");
		}

		if (invalidVpidValueCount > 0) {
			fail(invalidVpidValueCount
					+ " threads returned with invalid traits.");
		}

		// If we get here, the test completed successfully
	}

	public void testGetIDState() throws Exception {

		String vpid = "1008590728V283240";
		Person person = getPersonByVPID(vpid);
		String idState = getPsDelegateService().getIDState(
				person.getVPIDEntityKey());
		assertEquals("P", idState);

		vpid = "1008590722V437868";
		person = getPersonByVPID(vpid);
		idState = getPsDelegateService().getIDState(person.getVPIDEntityKey());
		assertEquals("P", idState);

	}

	// TODO no need to test as nothing changed in DC
	public void testIsRequestIDStateChangeError() throws Exception {
		// String vpid = "2000001496V976009";
		String vpid = "1008590775V635010";
		Person person = getPersonByVPID(vpid);

		boolean result = false;
		try {
			getPsDelegateService().requestIDStateChange(
					person.getVPIDEntityKey(),
					person.getEnrollmentDetermination().getEnrollmentStatus());
		} catch (ServiceException ex) {
			result = true;
		}

	}

	/*
	 * public void testIsCreatePreferFacilityError() throws Exception { //String
	 * vpid = "2000001496V976009"; String vpid = "1008590736V333355"; Person
	 * person = getPersonByVPID(vpid);
	 * 
	 * boolean result = false; try{ assertNotNull(person);
	 * //getPsDelegateService().addPreferredTreatingFacility(person); } catch
	 * (ServiceException ex) { result = true; }
	 * 
	 * }
	 */

	
	//CR 11776
	public void testGetSubmittedIdentityTraits() throws Exception {
		VPIDEntityKey key = CommonEntityKeyFactory
				.createVPIDEntityKey("0000001008590798V490483000000");
		
		PersonIdentityTraits traits = getPsDelegateService().getSubmittedIdentityTraits(key);
		assertNotNull(traits);
		System.out.println("id state: " + traits.getIDState());
		System.out.println("vpid: " + traits.getVpid());
		
	}
	
	
	//CR 11776
	public void testGetSites() throws Exception {
		String vpid = "0000001001170375V094875000000";

		Set sites = getPsDelegateService().getSites(CommonEntityKeyFactory.createVPIDEntityKey(vpid));
		// assertTrue(sites.size() > 0);
		System.out.println(sites.size());
		Iterator sit = sites.iterator();

		assertNotNull(sit);

		while (sit.hasNext()) {
			SiteIdentity sid = (SiteIdentity) sit.next();
			// System.out.println(sid.toString());
			assertNotNull(sid.getDfn());
			assertTrue(sid.getDfn().length() > 0);
			System.out.println("dfn: " + sid.getDfn());
			System.out.println("facility nanme:"
					+ sid.getVaFacility().getFacilityName());
			System.out.println("station#: "
					+ sid.getVaFacility().getStationNumber());
			System.out.println("code: " + sid.getVaFacility().getCode());
			System.out.println("facility Identifier: "
					+ sid.getVaFacility().getIdentifier());
			System.out.println("facility visn id: "
					+ sid.getVaFacility().getVisnId());
			// System.out.println("vpid: " + sid.getPerson().getVPIDValue());
			System.out.println("facility # and name: "
					+ sid.getVaFacility().getSiteNumberAndName());
			// System.out.println(sid.getEntityKey().getKeyValue());
		}
	}



	private Person getPersonByVPID(String shortVPID) throws Exception {
		// System.out.println(CommonEntityKeyFactory.createVPIDEntityKey(shortVPID));
		return getPersonService().getPerson(
				CommonEntityKeyFactory.createVPIDEntityKey(shortVPID));
	}

	public void testGetVPIDbyDFNandStationNum() throws Exception {
		String dfn = "0000001008591266V400774000000";
		String stationNumber = "200ESR";

		VPIDEntityKey vpid = getPsDelegateService().getVPID(dfn, stationNumber);
		assertNotNull(vpid);
		assertNotNull(vpid.getKeyValue());
		assertEquals("0000001008591266V400774000000", vpid.getVPID());
		//System.out.println(vpid.toString());

	}

	protected boolean traitsEqual(PersonIdentityTraits sourceTraits,
			PersonIdentityTraits targetTraits) {
		Name sourceName = sourceTraits.getLegalName();
		Name targetName = targetTraits.getLegalName();
		if ((sourceName.getFamilyName().equals(targetName.getFamilyName()))
				&& (sourceName.getGivenName().equals(targetName.getGivenName()))
				&& (sourceTraits.getVpid().getVPID().equals(targetTraits
						.getVpid().getVPID()))
				&& (sourceTraits.getSsn().getSsnText().equals(targetTraits
						.getSsn().getSsnText()))
				&& (sourceTraits.getGender().getName().equals(targetTraits
						.getGender().getName()))) {
			return true;
		} else {
			return false;
		}
	}

	protected String getPsimVpidValue(String vpidValue) throws Exception {
		return PSDelegateServiceTest.getPsimVpidValue(vpidValue,
				getPsDelegateService());
	}

	public static PersonIdentityTraits getIdentityTraits(String vpidValue,
			PSDelegateService psDelegateService) throws Exception {
		VPIDEntityKey vpidKey = CommonEntityKeyFactory
				.createVPIDEntityKey(vpidValue);
		return psDelegateService.getIdentityTraits(vpidKey);
	}

	public static String getPsimVpidValue(String vpidValue,
			PSDelegateService psDelegateService) throws Exception {
		PersonIdentityTraits traits = getIdentityTraits(vpidValue,
				psDelegateService);
		return traits.getVpid().getVPID();
	}

	protected void invalidVpidValue(String vpidValue, String psimVpidValue) {
		fail("Invalid VPID returned from PSIM.  Passed in VPID value of '"
				+ vpidValue + "'," + " but got back PSIM VPID value of '"
				+ psimVpidValue + "'.");
	}

	protected void validVpidValue(String vpidValue, String psimVpidValue) {
		System.out
				.println("Valid VPID returned from PSIM.  Passed in VPID value of '"
						+ vpidValue
						+ "' and got back PSIM VPID value of '"
						+ psimVpidValue + "'.");
	}

	protected void validTraits(PersonIdentityTraits traits) {
		System.out.println("Valid traits returned from PSIM: "
				+ getTraitsAsString(traits));
	}

	protected void invalidTraits(PersonIdentityTraits currentTraits,
			PersonIdentityTraits prevTraits) {
		System.out.println("Invalid traits returned.\nOne set of traits: "
				+ getTraitsAsString(currentTraits)
				+ ".\nAnother set of traits: " + getTraitsAsString(prevTraits));
	}

	protected String getTraitsAsString(PersonIdentityTraits traits) {
		Name name = traits.getLegalName();
		return traits.getVpid().getVPID() + ", " + name.getGivenName() + " "
				+ name.getFamilyName() + ", "
				+ traits.getSsn().getFormattedSsnText() + ", "
				+ traits.getGender().getName();
	}

	protected void timeoutVpidValue(String vpidValue) {
		System.out.println("Thread timed out.  Passed in VPID value of '"
				+ vpidValue + "'.");
	}

	protected void displaySummaryInfo(int totalSeconds, int totalThreads,
			int threadsNotCompleted) {
		System.out.println("Statistics after " + totalSeconds + " seconds.");
		int threadsComplete = totalThreads - threadsNotCompleted;
		System.out.println("Total threads: " + totalThreads);
		System.out.println("Threads complete: " + threadsComplete);
		System.out.println("Threads not complete: " + threadsNotCompleted);
		System.out.println("Percent of threads complete: "
				+ (((int) (threadsComplete / totalThreads)) * 100) + "%");
		System.out.println();
	}

	protected void displayVpidSummaryInfo(int timeoutCount, int validVpidCount,
			int invalidVpidCount, int timeoutVpidCount) {
		int totalVpidCount = validVpidCount + invalidVpidCount
				+ timeoutVpidCount;
		System.out.println();
		System.out.println("Final Summary Information.");
		System.out.println("Total seconds to complete JUnit: " + timeoutCount);
		System.out.println("Total valid VPID values: " + validVpidCount);
		System.out.println("Total invalid VPID values: " + invalidVpidCount);
		System.out.println("Total threads that didn't return: "
				+ timeoutVpidCount);
		System.out.println("Percent of successful returns: "
				+ (((int) (validVpidCount / totalVpidCount)) * 100) + "%");
	}
}

class TestVpidThread extends Thread {
	private PSDelegateService psDelegateService = null;
	private String vpidValue = null;
	private PersonIdentityTraits traits = null;

	public TestVpidThread(String vpidValue, PSDelegateService psDelegateService) {
		if (StringUtils.isEmpty(vpidValue)) {
			throw new RuntimeException("VPID value must not be empty.");
		}

		if (psDelegateService == null) {
			throw new RuntimeException("PSDelegateService can't be null.");
		}

		this.vpidValue = vpidValue;
		this.psDelegateService = psDelegateService;
	}

	public boolean validVpidReturned() {
		return (vpidValue.equals(getPsimVpidValue()));
	}

	public String getVpidValue() {
		return vpidValue;
	}

	public String getPsimVpidValue() {
		return traits.getVpid().getVPID();
	}

	public PersonIdentityTraits getTraits() {
		return traits;
	}

	public void run() {
		try {
			System.out.println("Initiating call to PSIM...");
			traits = PSDelegateServiceTest.getIdentityTraits(vpidValue,
					psDelegateService);
			System.out.println("PSIM call returned.");
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
}