package gov.va.vinci.dart.db;

import java.util.List;

import gov.va.vinci.dart.common.SingletonShim;
import gov.va.vinci.dart.common.exception.ValidationException;
import gov.va.vinci.dart.common.test.BusinessIntegrationTest;
import gov.va.vinci.dart.biz.OperationalRequest;
import gov.va.vinci.dart.biz.OperationalStudy;
import gov.va.vinci.dart.biz.Person;
import gov.va.vinci.dart.biz.RequestStatus;
import gov.va.vinci.dart.biz.TestResearchStudy;
import gov.va.vinci.dart.service.DartObjectFactory;
import gov.va.vinci.dart.wf2.WfOperationalRequest;

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

public class TestOperationalRequestDAO extends BusinessIntegrationTest {

	@BeforeTest
	public void setup() {
		SingletonShim.getBean(DartObjectFactory.class);
	}

	@Test
	public void testOne() throws Exception {
		
		OperationalRequest req = DartObjectFactory.getInstance().getOperationalRequestDAO().findById(-1);
		Assert.assertNull(req);
	}
	
	@Test
	public void testTwo() throws Exception {
		
		List<OperationalRequest> reqList = DartObjectFactory.getInstance().getOperationalRequestDAO().listAll();
		Assert.assertNotNull(reqList);
		Assert.assertTrue(reqList.size() > 0);
		
		OperationalRequest req = reqList.get(0);
		Assert.assertNotNull(req);
		
		Person requestor = req.getRequestor();
		Assert.assertNotNull(requestor);
		Assert.assertTrue(requestor.getId() > 0);

		List<OperationalRequest> reqlist = DartObjectFactory.getInstance().getOperationalRequestDAO().listByName(requestor.getId(), "e");
		Assert.assertNotNull(reqlist);
	}

	@Test
	public void testThree() throws Exception {

		Person pers = DartObjectFactory.getInstance().getPersonDAO().findById(1006);
		List<OperationalStudy> activityList = DartObjectFactory.getInstance().getOperationalStudyDAO().listAll();
		Assert.assertNotNull(activityList);
		Assert.assertTrue(activityList.size() > 0);
		
		OperationalStudy activity = activityList.get(0);
		Assert.assertNotNull(activity);
		Assert.assertTrue(activity.getId() > 0);
		
		// create request 1 so we'll have something to work with
		OperationalRequest req = OperationalRequest.create("test request 1", pers, activity, "DNS");

		Assert.assertNotNull(req);
		Assert.assertTrue(req.getId() > 0);
		Assert.assertNotNull(req.getDataSources());
		
//		Assert.assertNotNull(req.getReviews());
		Assert.assertNotNull(req.getAllReviews());

		Assert.assertNotNull(req.getParticipants());
		Assert.assertNotNull(req.getDocuments());
		Assert.assertNotNull(req.getEvents());
		Assert.assertNotNull(req.getNarratives());
		Assert.assertNotNull(req.getSites());
		
		OperationalRequest req2 = DartObjectFactory.getInstance().getOperationalRequestDAO().findById(req.getId());
		Assert.assertNotNull(req2);
		Assert.assertEquals(req2, req);
		
		try {
			req.modify(null, "office", "justification", "DNS");
			Assert.fail("Expected ValidationException");
		}catch (ValidationException e) {}
		
		// VINCI-58
		req.modify("name one", "office", TestResearchStudy.longString(3000), "DNS");
	}

	@Test
	public void testFour() throws Exception {

		List<OperationalRequest> reqList = DartObjectFactory.getInstance().getOperationalRequestDAO().listAll();
		Assert.assertNotNull(reqList);
		Assert.assertTrue(reqList.size() > 0);
	}

	@Test
	public void testFive() throws Exception {

		Person pers = DartObjectFactory.getInstance().getPersonDAO().findById(1006);
		List<OperationalStudy> activityList = DartObjectFactory.getInstance().getOperationalStudyDAO().listAll();
		Assert.assertNotNull(activityList);
		Assert.assertTrue(activityList.size() > 0);
		
		OperationalStudy activity = activityList.get(0);
		Assert.assertNotNull(activity);
		Assert.assertTrue(activity.getId() > 0);
		
		// create request 1 so we'll have something to work with
		OperationalRequest req = OperationalRequest.create("test request 1", pers, activity, "DNS");

		Assert.assertNotNull(req);
		Assert.assertTrue(req.getId() > 0);
		Assert.assertEquals(req.getActivity(), activity);
		
		List<OperationalRequest> reqList = DartObjectFactory.getInstance().getOperationalRequestDAO().listByActivityId(activity.getId());
		Assert.assertNotNull(reqList);
		Assert.assertTrue(reqList.size() > 0);
		Assert.assertTrue(reqList.contains(req));
	}

	@Test
	public void testSix() throws Exception {

		Person pers = DartObjectFactory.getInstance().getPersonDAO().findById(1006);
		List<OperationalStudy> activityList = DartObjectFactory.getInstance().getOperationalStudyDAO().listAll();
		Assert.assertNotNull(activityList);
		Assert.assertTrue(activityList.size() > 0);
		
		OperationalStudy activity = activityList.get(0);
		Assert.assertNotNull(activity);
		Assert.assertTrue(activity.getId() > 0);
		
		// create request 1 so we'll have something to work with
		OperationalRequest req = OperationalRequest.create("test request 1", pers, activity, "DNS");

		Assert.assertNotNull(req);
		Assert.assertTrue(req.getId() > 0);
		Assert.assertEquals(req.getActivity(), activity);
		
		List<OperationalRequest> reqList = DartObjectFactory.getInstance().getOperationalRequestDAO().listByRequestor(pers.getId());
		Assert.assertNotNull(reqList);
		Assert.assertTrue(reqList.size() > 0);
		Assert.assertTrue(reqList.contains(req));
	}

	@Test
	public void testSeven() throws Exception {

		Person pers = DartObjectFactory.getInstance().getPersonDAO().findById(1006);
		List<OperationalStudy> activityList = DartObjectFactory.getInstance().getOperationalStudyDAO().listAll();
		Assert.assertNotNull(activityList);
		Assert.assertTrue(activityList.size() > 0);
		
		OperationalStudy activity = activityList.get(0);
		Assert.assertNotNull(activity);
		Assert.assertTrue(activity.getId() > 0);
		
		// create request 1 so we'll have something to work with
		OperationalRequest req = OperationalRequest.create("test request 1", pers, activity, "DNS");

		Assert.assertNotNull(req);
		Assert.assertTrue(req.getId() > 0);
		Assert.assertEquals(req.getActivity(), activity);
		
		List<OperationalRequest> reqList = DartObjectFactory.getInstance().getOperationalRequestDAO().listRecentByRequestor(pers.getId(), 100);
		Assert.assertNotNull(reqList);
		Assert.assertTrue(reqList.size() > 0);
		Assert.assertTrue(reqList.contains(req));
	}

	@Test
	public void testEight() throws Exception {

		Person pers = DartObjectFactory.getInstance().getPersonDAO().findById(1006);
		List<OperationalStudy> activityList = DartObjectFactory.getInstance().getOperationalStudyDAO().listAll();
		Assert.assertNotNull(activityList);
		Assert.assertTrue(activityList.size() > 0);
		
		OperationalStudy activity = activityList.get(0);
		Assert.assertNotNull(activity);
		Assert.assertTrue(activity.getId() > 0);

		Assert.assertNotNull(pers);
		Assert.assertNotNull(pers.getName());
		Assert.assertTrue(pers.getName().length() > 0);
		
		// create request 1 so we'll have something to work with
		OperationalRequest req = OperationalRequest.create("test request 1", pers, activity, "DNS");

		Assert.assertNotNull(req);
		Assert.assertTrue(req.getId() > 0);
		Assert.assertEquals(req.getActivity(), activity);
		
//		Assert.assertNotNull(req.getReviews());
//		Assert.assertEquals(req.getReviews().size(), 0);
		Assert.assertNotNull(req.getAllReviews());
		Assert.assertEquals(req.getAllReviews().size(), 0);
		
		OperationalRequest amendment = DartObjectFactory.getInstance().getOperationalRequestDAO().findMostRecentAmendment(req.getId());
		Assert.assertNull(amendment);
		
		req.submit(pers.getName());
		req.setWorkflowState(WfOperationalRequest.OPS_FINAL_REVIEW_STATE);  // required to mimic the operational request workflow

		req.approve(null, pers.getName());
		
		// now how do you propose to test when it has an amendment?
	}

	@Test
	public void testNine() throws Exception {

		Person pers = DartObjectFactory.getInstance().getPersonDAO().findById(1006);
		List<OperationalStudy> activityList = DartObjectFactory.getInstance().getOperationalStudyDAO().listAll();
		Assert.assertNotNull(activityList);
		Assert.assertTrue(activityList.size() > 0);
		
		OperationalStudy activity = activityList.get(0);
		Assert.assertNotNull(activity);
		Assert.assertTrue(activity.getId() > 0);
		
		// create request 1 so we'll have something to work with
		OperationalRequest req = OperationalRequest.create("test request 1", pers, activity, "DNS");

		Assert.assertNotNull(req);
		Assert.assertTrue(req.getId() > 0);
		Assert.assertEquals(req.getActivity(), activity);
		
		// need to submit that request to guarantee there is something to see in the list
		req.submit(pers.getName()); 

		Assert.assertEquals(req.getStatus(), RequestStatus.SUBMITTED);
		
		List<OperationalRequest> reqList = DartObjectFactory.getInstance().getOperationalRequestDAO().listAllButInitiated();
		Assert.assertNotNull(reqList);
		Assert.assertTrue(reqList.contains(req));

		reqList = DartObjectFactory.getInstance().getOperationalRequestDAO().listAllSubmitted();
		Assert.assertNotNull(reqList);
		Assert.assertTrue(reqList.contains(req));

	}

}
