package gov.va.vinci.dart.json.builder;

import gov.va.vinci.dart.biz.Activity;
import gov.va.vinci.dart.biz.Person;
import gov.va.vinci.dart.biz.Request;
import gov.va.vinci.dart.biz.Role;
import gov.va.vinci.dart.common.SingletonShim;
import gov.va.vinci.dart.common.test.BusinessIntegrationTest;
import gov.va.vinci.dart.db.ActivityDAO;
import gov.va.vinci.dart.db.PersonDAO;
import gov.va.vinci.dart.json.ActivityView;
import gov.va.vinci.dart.service.DartObjectFactory;

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

public class TestActivityViewBuilder extends BusinessIntegrationTest {

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

	@Test
	public void testOne() throws Exception {
		ActivityViewBuilder builder = new ActivityViewBuilder();
		
		ActivityView av = builder.build(null, null, null);
		Assert.assertNotNull(av);
		Assert.assertEquals(av.getActivityId(), 0);
		Assert.assertEquals(av.getType(), Request.DATA_ACCESS);
	}
	
	@Test
	public void testTwo() throws Exception {
		
		ActivityDAO ad = DartObjectFactory.getInstance().getActivityDAO();
		Activity activity = ad.findById(1);
		
		Assert.assertNotNull(activity);
		Assert.assertTrue(activity.getId() > 0);

		Request request = activity.getFirstRequest();

		Assert.assertNotNull(request);
		Assert.assertTrue(request.getId() > 0);

		// give the mock test request some data values for good measure
		
		if (request.getIrbNumber() == null || request.getIrbNumber().length() == 0) {
			request.setIrbNumber("IRB Approval Number");
		}
		
		if (request.getIrbExpiration() == null) {
			request.setIrbExpiration(new java.util.Date());
		}

		boolean requestSubmitted = (request.getSubmittedOn() != null); 

		String requestType = Request.DATA_ACCESS;
		if( request.getRequestType() == 4 ) {
			requestType = Request.OPERATIONS_DATA_ACCESS;
		}
		
		Person pers = request.getRequestor();

		Assert.assertNotNull(pers);
		Assert.assertTrue(pers.getId() > 0);

		ActivityViewBuilder builder = new ActivityViewBuilder();
		
		try {
			builder.build(activity, null, null);
			Assert.fail("Expected NullPointerException");
		}
		catch (NullPointerException e) {}

		try {
			builder.build(activity, request, null);
			Assert.fail("Expected NullPointerException");
		}
		catch (NullPointerException e) {}

		ActivityView av = builder.build(activity, request, pers);

		Assert.assertNotNull(av);
		Assert.assertEquals(av.getActivityId(), activity.getId());
		Assert.assertEquals(av.getType(), requestType);
		Assert.assertNotNull(av.getShortName());
		Assert.assertNotNull(av.getOfficialName());
		Assert.assertNotNull(av.getActivityStartDate());
		Assert.assertNotNull(av.getActivityEndDate());
		Assert.assertNotNull(av.getiRBApprovalNumber());
		Assert.assertNotNull(av.getiRBExpirationDate());
		Assert.assertNotNull(av.getTrackingNumber());
		Assert.assertTrue( (av.getRequestSubmittedDate() != null) == requestSubmitted);
		Assert.assertNotNull(av.getRequestor());
		
	}
	
	@Test
	public void testThree() throws Exception {
		
		ActivityDAO ad = DartObjectFactory.getInstance().getActivityDAO();
		Activity activity = ad.findById(1);
		
		Assert.assertNotNull(activity);
		Assert.assertTrue(activity.getId() > 0);
	
		Request request = activity.getFirstRequest();
	
		Assert.assertNotNull(request);
		Assert.assertTrue(request.getId() > 0);
	
		Person pers = request.getRequestor();
	
		Assert.assertNotNull(pers);
		Assert.assertTrue(pers.getId() > 0);
	
		ActivityViewBuilder builder = new ActivityViewBuilder();
		
		// activity is NOT editable to super user
		ActivityView av = builder.build(activity, request, findASuperUser());
		Assert.assertNotNull(av);
		Assert.assertFalse(av.isEditable());

		// activity is just as editable to non-super user as the request
		av = builder.build(activity, request, findANonSuperUser());
		Assert.assertNotNull(av);
		
		Assert.assertEquals(av.isEditable(), request.isEditable(null));

	}
	
	private Person findASuperUser() {
		PersonDAO pd = DartObjectFactory.getInstance().getPersonDAO();
		
		
		for (Person pers : pd.listAll()) {
			if (pers.hasRole(Role.SUPER_USER) == true) {
				return pers;
			}
		}

		Person pers = pd.listAll().get(0);
		
		pers.getRoles().add(Role.SUPER_USER);
		
		return pers;
	}
	
	private Person findANonSuperUser() {
		PersonDAO pd = DartObjectFactory.getInstance().getPersonDAO();
		
		
		for (Person pers : pd.listAll()) {
			if (pers.hasRole(Role.SUPER_USER) == false) {
				return pers;
			}
		}

		Person pers = pd.listAll().get(0);
		
		pers.getRoles().remove(Role.SUPER_USER);
		
		return pers;
	}

}
