package gov.va.vinci.dart;

import static org.mockito.Mockito.mock;
import gov.va.vinci.dart.biz.DartRequest;
import gov.va.vinci.dart.biz.DocumentTemplate;
import gov.va.vinci.dart.biz.ResearchStudy;
import gov.va.vinci.dart.common.SingletonShim;
import gov.va.vinci.dart.common.exception.ValidationException;
import gov.va.vinci.dart.common.json.ErrorView;
import gov.va.vinci.dart.common.test.BusinessIntegrationTest;
import gov.va.vinci.dart.dms.biz.Document;
import gov.va.vinci.dart.json.DocumentIdView;
import gov.va.vinci.dart.json.DocumentListView;
import gov.va.vinci.dart.json.DocumentTemplateListView;
import gov.va.vinci.dart.json.DocumentTemplateView;
import gov.va.vinci.dart.json.DocumentView;
import gov.va.vinci.dart.json.GroupDocumentListView;
import gov.va.vinci.dart.json.RequestIdView;
import gov.va.vinci.dart.json.RequestLocationDocumentListView;
import gov.va.vinci.dart.json.RequestParticipantDocumentListView;
import gov.va.vinci.dart.service.DartObjectFactory;
import gov.va.vinci.dart.usr.CustomAuthentication;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.core.context.SecurityContextHolder;
import org.testng.Assert;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

public class TestDocumentController extends BusinessIntegrationTest {

	@BeforeTest
	public void setup() {
		SingletonShim.getBean(DartObjectFactory.class);
		
		CustomAuthentication token = new CustomAuthentication("DNS", null, "password", "details", "principal");

		try {
			DartObjectFactory.getInstance().getUserManager().login(token);
			SecurityContextHolder.getContext().setAuthentication(token);
		} 
		catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Test
	public void testOne() throws Exception {
		Assert.assertTrue(DocumentController.isAllowedFileExtension("doc"));
		Assert.assertTrue(DocumentController.isAllowedFileExtension("docx"));
		Assert.assertTrue(DocumentController.isAllowedFileExtension("pdf"));
		Assert.assertFalse(DocumentController.isAllowedFileExtension("xls"));
		Assert.assertFalse(DocumentController.isAllowedFileExtension(null));
		Assert.assertFalse(DocumentController.isAllowedFileExtension(""));
	}

	@Test
	public void testTwo() throws Exception {
		createATestDocument();
		
		List<Document> doclist = DartObjectFactory.getInstance().getDocumentDAO().listAll();
		Assert.assertNotNull(doclist);
		Assert.assertTrue(doclist.size() > 0);
		Document testDoc = doclist.get(0);
		Assert.assertNotNull(testDoc);
		
		DocumentController dsc = SingletonShim.getBean(DocumentController.class);
		
		Object obj = dsc.listDocumentById(null);
		Assert.assertNotNull(obj);
		Assert.assertTrue(obj instanceof ErrorView);
		Assert.assertNotEquals(((ErrorView)obj).getMessage().get("text"), "OK");
		
		DocumentIdView div = new DocumentIdView();
		
		obj = dsc.listDocumentById(div);
		Assert.assertNotNull(obj);
		Assert.assertTrue(obj instanceof ErrorView);
		Assert.assertNotEquals(((ErrorView)obj).getMessage().get("text"), "OK");
	
		div.setDocumentId(testDoc.getId());
		obj = dsc.listDocumentById(div);
		Assert.assertNotNull(obj);
		Assert.assertTrue(obj instanceof DocumentView);
		
		DocumentView dv = (DocumentView)obj;
		Assert.assertEquals(dv.getId(), testDoc.getId());
		Assert.assertEquals(dv.getHeadId(), testDoc.getId());
		Assert.assertTrue(dv.isOnlyOneVersion());
		Assert.assertNotNull(dv.getDocVersions());
		Assert.assertTrue(dv.getDocVersions().size() < 1);
		Assert.assertEquals(dv.getVersionNumber(), 1);
		
		// TODO- if the doc had a subsequent version, try to retrieve the most recent version
	}

	@Test
	public void testThree() throws Exception {
		DocumentController dsc = SingletonShim.getBean(DocumentController.class);
		
		HttpServletRequest request = mock(HttpServletRequest.class);
		Assert.assertNotNull(request);
		
		Object obj = dsc.listDocumentTemplates(request);
		Assert.assertNotNull(obj);
		Assert.assertTrue(obj instanceof DocumentTemplateListView);
		
		DocumentTemplateListView dtlv = (DocumentTemplateListView)obj;
		Assert.assertNotNull(dtlv.getTemplates());
		Assert.assertTrue(dtlv.getTemplates().size() > 0);
		
		for (DocumentTemplateView dtv : dtlv.getTemplates()) {
			Assert.assertNotNull(dtv);
			Assert.assertTrue(dtv.getId() > 0);
			Assert.assertNotNull(dtv.getDescription());
			Assert.assertNotNull(dtv.getName());
			Assert.assertNotNull(dtv.getActivityType());
			Assert.assertTrue(dtv.getSortOrder() > 0);
		}
	}

	@Test
	public void testFour() throws Exception {
		DocumentController dsc = SingletonShim.getBean(DocumentController.class);
		
		ResearchStudy.findById(1);

		List<DartRequest> reqList = DartRequest.listAll();
		Assert.assertNotNull(reqList);
		Assert.assertTrue(reqList.size() > 0);

		DartRequest req = reqList.get(0);

		Object obj = dsc.listDocuments(req.getId());
		
		Assert.assertNotNull(obj);
		Assert.assertTrue(obj instanceof DocumentListView);
		DocumentListView dlv = (DocumentListView)obj;
		
		Assert.assertNotNull(dlv.getLocations());
		Assert.assertNotNull(dlv.getParticipants());
		
		// TODO- now what?
	}

	@Test
	public void testFive() throws Exception {
		DocumentController dsc = SingletonShim.getBean(DocumentController.class);
		
		ResearchStudy.findById(1);

		List<DartRequest> reqList = DartRequest.listAll();
		Assert.assertNotNull(reqList);
		Assert.assertTrue(reqList.size() > 0);

		DartRequest req = reqList.get(0);

		Object obj = dsc.listDocumentsLocations(req.getId());
		
		Assert.assertNotNull(obj);
		Assert.assertTrue(obj instanceof RequestLocationDocumentListView);
		RequestLocationDocumentListView dlv = (RequestLocationDocumentListView)obj;
		
		Assert.assertNotNull(dlv.getLocations());
		
		// TODO- now what?
	}

	@Test
	public void testSix() throws Exception {
		DocumentController dsc = SingletonShim.getBean(DocumentController.class);
		
		ResearchStudy.findById(1);

		List<DartRequest> reqList = DartRequest.listAll();
		Assert.assertNotNull(reqList);
		Assert.assertTrue(reqList.size() > 0);

		DartRequest req = reqList.get(0);

		Object obj = dsc.listDocumentsParticipants(req.getId());
		
		Assert.assertNotNull(obj);
		Assert.assertTrue(obj instanceof RequestParticipantDocumentListView);
		RequestParticipantDocumentListView dlv = (RequestParticipantDocumentListView)obj;
		
		Assert.assertNotNull(dlv.getParticipants());
		
		// TODO- now what?
	}

	@Test
	public void testSeven() throws Exception {
		DocumentController dsc = SingletonShim.getBean(DocumentController.class);
		
		ResearchStudy.findById(1);

		List<DartRequest> reqList = DartRequest.listAll();
		Assert.assertNotNull(reqList);
		Assert.assertTrue(reqList.size() > 0);

		DartRequest req = reqList.get(0);

		Object obj = dsc.listDocumentsByRequest(null);
		Assert.assertNotNull(obj);
		Assert.assertTrue(obj instanceof ErrorView);
		Assert.assertNotEquals(((ErrorView)obj).getMessage().get("text"), "OK");
		
		RequestIdView riv = new RequestIdView();
		
		obj = dsc.listDocumentsByRequest(riv);
		Assert.assertNotNull(obj);
		Assert.assertTrue(obj instanceof ErrorView);
		Assert.assertNotEquals(((ErrorView)obj).getMessage().get("text"), "OK");

		riv.setRequestId(req.getId());
		obj = dsc.listDocumentsByRequest(riv);
		
		Assert.assertNotNull(obj);
		Assert.assertTrue(obj instanceof DocumentListView);
		DocumentListView dlv = (DocumentListView)obj;
		
		Assert.assertNotNull(dlv.getLocations());
		Assert.assertNotNull(dlv.getParticipants());
		
		// TODO- now what?
	}
	
	@Test
	public void testEight() throws Exception {
		DocumentController dsc = SingletonShim.getBean(DocumentController.class);
		
		ResearchStudy.findById(1);

		List<DartRequest> reqList = DartRequest.listAll();
		Assert.assertNotNull(reqList);
		Assert.assertTrue(reqList.size() > 0);

		DartRequest req = reqList.get(0);

		Object obj = dsc.listAdminDocumentsByRequest(null);
		Assert.assertNotNull(obj);
		Assert.assertTrue(obj instanceof ErrorView);
		Assert.assertNotEquals(((ErrorView)obj).getMessage().get("text"), "OK");
		
		RequestIdView riv = new RequestIdView();
		
		obj = dsc.listAdminDocumentsByRequest(riv);
		Assert.assertNotNull(obj);
		Assert.assertTrue(obj instanceof ErrorView);
		Assert.assertNotEquals(((ErrorView)obj).getMessage().get("text"), "OK");

		riv.setRequestId(req.getId());
		obj = dsc.listAdminDocumentsByRequest(riv);
		
		Assert.assertNotNull(obj);
		Assert.assertTrue(obj instanceof DocumentListView);
		DocumentListView dlv = (DocumentListView)obj;
		
		Assert.assertNotNull(dlv.getLocations());
		Assert.assertNotNull(dlv.getParticipants());
		
		// TODO- now what?
	}
	
	@Test
	public void testNine() throws Exception {
		DocumentController dsc = SingletonShim.getBean(DocumentController.class);
		
		ResearchStudy.findById(1);

		List<DartRequest> reqList = DartRequest.listAll();
		Assert.assertNotNull(reqList);
		Assert.assertTrue(reqList.size() > 0);

		DartRequest req = reqList.get(0);

		Object obj = dsc.listAdminDocumentsForAllGroups(null);
		Assert.assertNotNull(obj);
		Assert.assertTrue(obj instanceof ErrorView);
		Assert.assertNotEquals(((ErrorView)obj).getMessage().get("text"), "OK");
		
		RequestIdView riv = new RequestIdView();
		
		obj = dsc.listAdminDocumentsForAllGroups(riv);
		Assert.assertNotNull(obj);
		Assert.assertTrue(obj instanceof ErrorView);
		Assert.assertNotEquals(((ErrorView)obj).getMessage().get("text"), "OK");

		riv.setRequestId(req.getId());
		obj = dsc.listAdminDocumentsForAllGroups(riv);
		
		Assert.assertNotNull(obj);
		Assert.assertTrue(obj instanceof GroupDocumentListView);
		GroupDocumentListView dlv = (GroupDocumentListView)obj;
		
		Assert.assertNotNull(dlv.getGroupDocuments());
		
		// TODO- now what?
	}
	
	@Test
	public void testTen() throws Exception {
		DocumentController dsc = SingletonShim.getBean(DocumentController.class);
		
		ResearchStudy.findById(1);

		List<DartRequest> reqList = DartRequest.listAll();
		Assert.assertNotNull(reqList);
		Assert.assertTrue(reqList.size() > 0);

		DartRequest req = reqList.get(0);

		Object obj = dsc.listAdminReviewDocumentsForAllGroups(null);
		Assert.assertNotNull(obj);
		Assert.assertTrue(obj instanceof ErrorView);
		Assert.assertNotEquals(((ErrorView)obj).getMessage().get("text"), "OK");
		
		RequestIdView riv = new RequestIdView();
		
		obj = dsc.listAdminReviewDocumentsForAllGroups(riv);
		Assert.assertNotNull(obj);
		Assert.assertTrue(obj instanceof ErrorView);
		Assert.assertNotEquals(((ErrorView)obj).getMessage().get("text"), "OK");

		riv.setRequestId(req.getId());
		obj = dsc.listAdminReviewDocumentsForAllGroups(riv);
		
		Assert.assertNotNull(obj);
		Assert.assertTrue(obj instanceof GroupDocumentListView);
		GroupDocumentListView dlv = (GroupDocumentListView)obj;
		
		Assert.assertNotNull(dlv.getGroupDocuments());
		
		// TODO- now what?
	}
	
	@Test
	public void testEleven() throws Exception {
		createATestDocument();

		List<Document> doclist = DartObjectFactory.getInstance().getDocumentDAO().listAll();
		Assert.assertNotNull(doclist);
		Assert.assertTrue(doclist.size() > 0);
		Document testDoc = doclist.get(0);
		Assert.assertNotNull(testDoc);

		DocumentController dsc = SingletonShim.getBean(DocumentController.class);

		HttpServletResponse response = new MockHttpServletResponse();
		dsc.viewDocument(String.valueOf(testDoc.getId()), response);
	
		// TODO- we should test this with a document that has content.
	
		// TODO- now what?
	}

	@Test
	public void testTwelve() throws Exception {
		DocumentController dsc = SingletonShim.getBean(DocumentController.class);

		HttpServletResponse response = new MockHttpServletResponse();
		
		dsc.viewDocument(null, response);
		
		Assert.assertNull(response.getContentType());
		
		// TODO- now what? (nothing should be written to the output stream - how do we test?)
	}

	@Test
	public void testThirteen() throws Exception {
		DocumentController dsc = SingletonShim.getBean(DocumentController.class);

		HttpServletResponse response = new MockHttpServletResponse();
		
		dsc.viewDocument("-1", response);
		
		Assert.assertNull(response.getContentType());
		
		// TODO- now what? (nothing should be written to the output stream - how do we test?)
	}

	private void createATestDocument() throws ValidationException {
		ResearchStudy.findById(1);

		List<DartRequest> reqList = DartRequest.listAll();
		Assert.assertNotNull(reqList);
		Assert.assertTrue(reqList.size() > 0);

		DartRequest req = reqList.get(0);
		
		List<DocumentTemplate> dtList = DocumentTemplate.listAll();
		Assert.assertNotNull(dtList);
		Assert.assertTrue(dtList.size() > 0);

		DocumentTemplate dt = dtList.get(0);
		Assert.assertNotNull(dt);
		
		Document doc = Document.create(req, dt, "DNS");
		Assert.assertNotNull(doc);
		Assert.assertTrue(doc.getId() > 0);
	}
	
	/*
	 * public void viewDocument()
	 * public void uploadDocument()
	 * 
	 */
}
