package gov.va.vinci.dart.db;

import java.util.List;

import org.testng.Assert;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

import gov.va.vinci.dart.common.SingletonShim;
import gov.va.vinci.dart.common.exception.ObjectNotFoundException;
import gov.va.vinci.dart.common.test.BusinessIntegrationTest;
import gov.va.vinci.dart.biz.Group;
import gov.va.vinci.dart.biz.Person;
import gov.va.vinci.dart.biz.Role;
import gov.va.vinci.dart.service.DartObjectFactory;

public class TestPersonDAO  extends BusinessIntegrationTest {

	@BeforeTest
	public void setup() {
		SingletonShim.getBean(DartObjectFactory.class);
	}
	
	@Test
	public void testOne() throws Exception {
		try {
			DartObjectFactory.getInstance().getPersonDAO().findById(0);
			Assert.fail("Expected ObjectNotFoundException");
		}
		catch (ObjectNotFoundException e) {}

		List<Person> personList = DartObjectFactory.getInstance().getPersonDAO().listAll();
		 
		Assert.assertNotNull(personList);
		Assert.assertTrue(personList.size() > 0);
	}
	
	@Test
	public void testTwo() throws Exception {
		try {
			DartObjectFactory.getInstance().getPersonDAO().findById(-1);
			Assert.fail("Expected ObjectNotFoundException");
		} catch (ObjectNotFoundException e) {}


		// find somebody to search for
		 List<Person> personList = DartObjectFactory.getInstance().getPersonDAO().listAll();
		 
		 Assert.assertNotNull(personList);
		 Assert.assertTrue(personList.size() > 0);
		 
		 Person pers = personList.get(0);
		 Assert.assertNotNull(pers);
		 Assert.assertTrue(pers.getId() > 0);
		 
		Person pers2 = DartObjectFactory.getInstance().getPersonDAO().findById(pers.getId());
		Assert.assertNotNull(pers2);
		Assert.assertEquals(pers2, pers);
	}
	
	@Test
	public void testThree() throws Exception {
		try {
			DartObjectFactory.getInstance().getPersonDAO().findByName(null);
			Assert.fail("Expected ObjectNotFoundException");
		} catch (ObjectNotFoundException e) {}

		try {
			DartObjectFactory.getInstance().getPersonDAO().findByName("");
			Assert.fail("Expected ObjectNotFoundException");
		} catch (ObjectNotFoundException e) {}

		try {
			DartObjectFactory.getInstance().getPersonDAO().findByName("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890");
			Assert.fail("Expected ObjectNotFoundException");
		} catch (ObjectNotFoundException e) {}

		// find somebody to search for
		 List<Person> personList = DartObjectFactory.getInstance().getPersonDAO().listAll();
		 
		 Assert.assertNotNull(personList);
		 Assert.assertTrue(personList.size() > 0);
		 
		 Person pers = personList.get(0);
		 Assert.assertNotNull(pers);
		 Assert.assertNotNull(pers.getName());
		 Assert.assertTrue(pers.getName().length() > 0);
		 
		Person pers2 = DartObjectFactory.getInstance().getPersonDAO().findByName(pers.getName());
		Assert.assertNotNull(pers2);
		Assert.assertEquals(pers2, pers);
	}

	@Test
	public void testFour() throws Exception {
		List<Person> personList = DartObjectFactory.getInstance().getPersonDAO().list(null);
		Assert.assertNotNull(personList);
		Assert.assertTrue(personList.size() > 0);

		personList = DartObjectFactory.getInstance().getPersonDAO().list("");
		Assert.assertNotNull(personList);
		Assert.assertTrue(personList.size() > 0);

		// assume nobody found with ~ in their name
		personList = DartObjectFactory.getInstance().getPersonDAO().list("~");
		Assert.assertNotNull(personList);
		Assert.assertFalse(personList.size() > 0);

		// assume somebody found with a in their name
		personList = DartObjectFactory.getInstance().getPersonDAO().list("a");
		Assert.assertNotNull(personList);
		Assert.assertTrue(personList.size() > 0);

	}

	@Test
	public void testFive() throws Exception {

		// find somebody to search for
		 List<Person> personList = DartObjectFactory.getInstance().getPersonDAO().listAll();
		 
		 Assert.assertNotNull(personList);
		 Assert.assertTrue(personList.size() > 0);

		 Group testGroup = null;
		 
		 for (Person pers : personList) {
			 Assert.assertNotNull(pers.getGroups());
			 if (pers.getGroups().size() > 0) {
				 testGroup = (Group)pers.getGroups().iterator().next();
				 break;
			 }
		 }

		 Assert.assertNotNull(testGroup);

		 // got all the people in that group
		 personList = DartObjectFactory.getInstance().getPersonDAO().listByGroup(testGroup.getId());

		 Assert.assertNotNull(personList);
		 Assert.assertTrue(personList.size() > 0);

		 // do all of the people listed have the correct group in their group list?
		 for (Person pers : personList) {
			 Assert.assertTrue(pers.getGroups().contains(testGroup));
		 }

		 // does the selected group have all the listed people?
		 for (Person pers : testGroup.getMembers()) {
			 Assert.assertTrue(personList.contains(pers));
		 }
		 
	}

	@Test
	public void testSix() throws Exception {

		// find somebody to search for
		 List<Person> personList = DartObjectFactory.getInstance().getPersonDAO().listAll();
		 
		 Assert.assertNotNull(personList);
		 Assert.assertTrue(personList.size() > 0);

		 Role testRole = null;
		 
		 for (Person pers : personList) {
			 Assert.assertNotNull(pers.getGroups());
			 if (pers.getRoles().size() > 0) {
				 testRole = (Role)pers.getRoles().iterator().next();
				 break;
			 }
		 }

		 Assert.assertNotNull(testRole);

		 // got all the people in that group
		 personList = DartObjectFactory.getInstance().getPersonDAO().listAllWithRole(testRole.getId());

		 Assert.assertNotNull(personList);
		 Assert.assertTrue(personList.size() > 0);

		 // do all of the people listed have the correct group in their group list?
		 for (Person pers : personList) {
			 Assert.assertTrue(pers.getRoles().contains(testRole));
		 }
	}	
}
