
package gov.va.med.cds.ars.model;

import gov.va.med.cds.ars.requestresponse.generated.DMPUniqueICNReportDataType;
import gov.va.med.cds.ars.requestresponse.generated.DMPUniqueICNReportFilterType;
import gov.va.med.cds.ars.requestresponse.generated.GeographicalAreaType;
import gov.va.med.cds.ars.requestresponse.generated.HTReportFilterType;
import gov.va.med.cds.ars.requestresponse.generated.HTReportSurveyType;
import gov.va.med.cds.ars.requestresponse.generated.HTReportType;
import gov.va.med.cds.ars.requestresponse.generated.HTResponseType;
import gov.va.med.cds.ars.requestresponse.generated.LocationReportDataType;
import gov.va.med.cds.ars.requestresponse.generated.ObjectFactory;
import gov.va.med.cds.ars.requestresponse.generated.ReportIDType;
//import gov.va.med.cds.ars.requestresponse.generated.ReportSurveyType;
import gov.va.med.cds.ars.requestresponse.generated.VR12LocationReportDataType;
import gov.va.med.cds.ars.requestresponse.generated.VR12ReportDataType;
import gov.va.med.cds.ars.requestresponse.generated.VR12ReportFilterType;
import gov.va.med.cds.junit.runners.Suite;
import gov.va.med.cds.junit.runners.SuiteAwareSpringRunner;
import gov.va.med.cds.testharness.AbstractBaseTest;
import gov.va.med.cds.util.StreamUtil;

import javax.annotation.Resource;
import javax.xml.bind.JAXBElement;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.core.io.FileSystemResource;
import org.springframework.test.context.ContextConfiguration;

@RunWith(SuiteAwareSpringRunner.class)
@ContextConfiguration(locations = { "classpath:gov/va/med/cds/ars/config/modelContext.xml",
		"classpath:gov/va/med/cds/ars/config/jaxbContext.xml" })
public class ModelMarshallerTest extends AbstractBaseTest {
	private ModelMarshallerInterface modelMarshaler;

	{
		System.setProperty("jdk.xml.maxOccurLimit", "200000000");
	}

	@Test
	@Suite(groups = { "checkintest" })
	public void testFilterUnmarshaller() throws Exception {
		Assert.assertNotNull(modelMarshaler);
	}

	@Test
	@Suite(groups = { "checkintest" })
	public void testDMPUniqueICNReportMarshaller() throws Exception {
		String validXmlInstance = StreamUtil
				.resourceToString(new FileSystemResource("./src/test/resources/model/DMPUniqueICNReport.xml"));

		// build model to Marshal
		HTReportType myDMPUniqueICNReport = createDMPUniqueICNReport();
		Assert.assertNotNull(myDMPUniqueICNReport);

		// Marshal model to XML string
		String marshaledXmlModel = modelMarshaler.marshalToXml(myDMPUniqueICNReport);
		logger.debug("marshaled output: " + marshaledXmlModel);

		// compare marshaled XML to valid instance document
		assertXMLSimilar(marshaledXmlModel, validXmlInstance);
	}

	private HTReportType createDMPUniqueICNReport() throws Exception {
		ObjectFactory objectFactory = new ObjectFactory();

		HTReportFilterType htReportFilter = objectFactory.createHTReportFilterType();

		DMPUniqueICNReportFilterType dmpUniqueICNReportFilter = objectFactory.createDMPUniqueICNReportFilterType();
		dmpUniqueICNReportFilter.setReportID(ReportIDType.DMP_UNIQUE_ICN_REPORT);
		XMLGregorianCalendar startDate = DatatypeFactory.newInstance().newXMLGregorianCalendar("2000-01-20");
		dmpUniqueICNReportFilter.setStartDate(startDate);
		XMLGregorianCalendar endDate = DatatypeFactory.newInstance().newXMLGregorianCalendar("2013-05-30");
		dmpUniqueICNReportFilter.setEndDate(endDate);
		GeographicalAreaType geographicArea = objectFactory.createGeographicalAreaType();
		geographicArea.setLocation("National");
		dmpUniqueICNReportFilter.setGeographicalArea(geographicArea);
		dmpUniqueICNReportFilter.setSurveyVersion("1.0");
		dmpUniqueICNReportFilter.setSurveyType("VHA_TEST_DMP_SURVEY");
		dmpUniqueICNReportFilter.setVendor("200T4");

		htReportFilter.setDMPUniqueICNReportFilter(dmpUniqueICNReportFilter);

		HTResponseType htResponse = objectFactory.createHTResponseType();
		DMPUniqueICNReportDataType dmpUniqueICNReportData = objectFactory.createDMPUniqueICNReportDataType();
		dmpUniqueICNReportData.setReportID(ReportIDType.DMP_UNIQUE_ICN_REPORT);
		dmpUniqueICNReportData.setNumberOfRecordsConsidered(123);
		LocationReportDataType locationReportData = objectFactory.createLocationReportDataType();
		locationReportData.setLocation("National");
		locationReportData.setRecordCount(987);
		dmpUniqueICNReportData.getReportData().add(locationReportData);
		htResponse.setDMPUniqueICNReportData(dmpUniqueICNReportData);

		HTReportType report = objectFactory.createHTReportType();

		report.setRequestID("TestRequestID");
		report.setRequest(htReportFilter);
		report.setResponse(htResponse);

		return report;
	}

	private HTReportType createVR12Report() throws Exception {
		ObjectFactory objectFactory = new ObjectFactory();

		HTReportFilterType htReportFilter = objectFactory.createHTReportFilterType();
		VR12ReportFilterType vr12ReportFilterType = objectFactory.createVR12ReportFilterType();
		vr12ReportFilterType.setReportID(ReportIDType.VR_12_STATISTICS);
		XMLGregorianCalendar startDate = DatatypeFactory.newInstance().newXMLGregorianCalendar("2000-01-20");
		vr12ReportFilterType.setStartDate(startDate);
		XMLGregorianCalendar endDate = DatatypeFactory.newInstance().newXMLGregorianCalendar("2013-05-30");
		vr12ReportFilterType.setEndDate(endDate);
		GeographicalAreaType geographicArea = objectFactory.createGeographicalAreaType();
		geographicArea.setLocation("National");
		vr12ReportFilterType.setGeographicalArea(geographicArea);
		vr12ReportFilterType.setSurveyType(HTReportSurveyType.VR_12_ADL);
		vr12ReportFilterType.setSurveyVersion("1.0");
		htReportFilter.setVR12ReportFilter(vr12ReportFilterType);

		HTResponseType htResponse = objectFactory.createHTResponseType();
		VR12ReportDataType vr12ReportDataType = objectFactory.createVR12ReportDataType();
		vr12ReportDataType.setReportID(ReportIDType.VR_12_STATISTICS);
		vr12ReportDataType.setNumberOfRecordsConsidered(567);
		VR12LocationReportDataType locationReportData = objectFactory.createVR12LocationReportDataType();
		locationReportData.setLocation("National");
		locationReportData.setRecordCount(987);
		locationReportData.setMentalAverage(12.34);
		locationReportData.setPhysicalAverage(78.9);
		vr12ReportDataType.getReportData().add(locationReportData);
		htResponse.setVR12ReportData(vr12ReportDataType);

		HTReportType report = objectFactory.createHTReportType();

		report.setRequestID("TestRequestID");
		report.setRequest(htReportFilter);
		report.setResponse(htResponse);

		return report;
	}

	@Test
	@Suite(groups = { "checkintest" })
	public void testVR12ReportMarshaller() throws Exception {
		String validXmlInstance = StreamUtil
				.resourceToString(new FileSystemResource("./src/test/resources/model/VR12NationalReport.xml"));

		// build model to Marshal
		HTReportType myVR12Report = createVR12Report();
		Assert.assertNotNull(myVR12Report);

		// Marshal model to XML string
		String marshaledXmlModel = modelMarshaler.marshalToXml(myVR12Report);
		logger.debug("marshaled output: " + marshaledXmlModel);

		// compare marshaled XML to valid instance document
		assertXMLSimilar(marshaledXmlModel, validXmlInstance);
	}

	@Resource
	public void setModelMarshaller(ModelMarshallerInterface modelMarshaller) {
		this.modelMarshaler = modelMarshaller;
	}

}
