

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


import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import gov.va.med.cds.ars.exception.ValidationException;
import gov.va.med.cds.ars.jaxb.JaxbHelper;
import gov.va.med.cds.ars.requestresponse.generated.HTReportFilterType;
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 java.io.IOException;

import javax.annotation.Resource;

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/filterContext.xml", 
                                     "classpath:gov/va/med/cds/ars/config/jaxbContext.xml" } )
public class HtUnmarshallerTest
    extends
    	AbstractBaseTest
{
    protected static final String ARS_REPORT_SCHEMA_LOCATION = "classpath:resources/HTReportFilter.xsd";
	private ReportFilterUnmarshallerInterface filterUnmarshaller;
	private JaxbHelper jaxbHelper;


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

    
    @Test
    @Suite( groups = { "checkintest" } ) 
    public void testHtDMPUnmarshaller( )
        throws Exception
    {
        String filterInstance = StreamUtil.resourceToString( new FileSystemResource(
                "./src/test/resources/filters/DMPFilter" ) );
        
        //unmarshal XML instance
        HTReportFilterType dmpUniqueICNReportFilter = filterUnmarshaller.unMarshalReportFilter( filterInstance, "HTReportFilter" );
        
        //marshal objects back to XML
        String marshalled = jaxbHelper.marshal( dmpUniqueICNReportFilter, ARS_REPORT_SCHEMA_LOCATION );
        logger.debug( "output: " + marshalled );

        //compare marshaled XML to original instance document
        assertXMLSimilar( marshalled, filterInstance );
    }
    
    
    @Test
    @Suite( groups = { "checkintest" } ) 
    public void testHtVR12Unmarshaller( )
        throws Exception
    {
        String filterInstance = StreamUtil.resourceToString( new FileSystemResource(
                "./src/test/resources/filters/VR12NationalFilter" ) );
        
        //unmarshal XML instance
        HTReportFilterType vr12ReportFilter = filterUnmarshaller.unMarshalReportFilter( filterInstance, "HTReportFilter" );
        
        //marshal objects back to XML
        String marshalled = jaxbHelper.marshal( vr12ReportFilter, ARS_REPORT_SCHEMA_LOCATION );
        logger.debug( "output: " + marshalled );

        //compare marshaled XML to original instance document
        assertXMLSimilar( marshalled, filterInstance );
    }
    
    
    @Test( expected = ValidationException.class )
    @Suite( groups = { "checkintest" } )
    public void testUnmarshallerValidationException( ) 
        throws IOException
    {
        String invalidFilterInstance = StreamUtil.resourceToString( new FileSystemResource(
                "./src/test/resources/filters/InvalidFilter" ) );
        
        //unmarshal invalid XML instance
        HTReportFilterType filterObjects = filterUnmarshaller.unMarshalReportFilter( invalidFilterInstance, "HTReportFilter" );
        assertNull( filterObjects ); 
    }
    
    
    @Test( expected = ValidationException.class )
    @Suite( groups = { "checkintest" } )
    public void testUnmarshallerNullReportIdValidationException( ) 
        throws IOException
    {
        String invalidFilterInstance = StreamUtil.resourceToString( new FileSystemResource(
                "./src/test/resources/filters/InvalidFilterBadReportID" ) );
        
        //unmarshal invalid XML instance
        HTReportFilterType filterObjects = filterUnmarshaller.unMarshalReportFilter( invalidFilterInstance, "HTReportFilter" );
        assertNull( filterObjects ); 
    }
    
    
    @Test( expected = ValidationException.class )
    @Suite( groups = { "checkintest" } )
    public void testUnmarshallerDateValidationException( ) 
        throws IOException
    {
        String invalidFilterInstance = StreamUtil.resourceToString( new FileSystemResource(
                "./src/test/resources/filters/InvalidFilterBadDate" ) );
        
        //unmarshal invalid XML instance
        HTReportFilterType filterObjects = filterUnmarshaller.unMarshalReportFilter( invalidFilterInstance, "HTReportFilter" );
        assertNull( filterObjects ); 
    }
    
    
	@Test
    @Suite( groups = { "checkintest" } )
    public void testUnmarshallerValidationExceptionMessage( ) 
    	throws IOException
    {
        String invalidFilterInstance = StreamUtil.resourceToString( new FileSystemResource(
                "./src/test/resources/filters/InvalidFilter" ) );
        
		try 
		{
			filterUnmarshaller.unMarshalReportFilter( invalidFilterInstance, "HTReportFilter" );
			assertNotNull( null ); //ensure exception thrown
		} 
		catch (Exception e) 
		{
			assertTrue( (e.getCause().toString().contains("[VR-12 ADL, Patient Satisfaction, All Surveys]")));  
		}

    }	
    
    
    @Test( expected = ValidationException.class )
    @Suite( groups = { "checkintest" } )
    public void testUnmarshallerBadLocationValidationException( ) 
        throws IOException
    {
        String invalidFilterInstance = StreamUtil.resourceToString( new FileSystemResource(
                "./src/test/resources/filters/InvalidDMPFilterBadLocation" ) );
        
        //unmarshal invalid XML instance
        HTReportFilterType filterObjects = filterUnmarshaller.unMarshalReportFilter( invalidFilterInstance, "HTReportFilter" );
        assertNull( filterObjects ); 
    }

    
    @Resource
    public void setFilterUnmarshaller(ReportFilterUnmarshallerInterface filterUnmarshaller) 
    {
        this.filterUnmarshaller = filterUnmarshaller;
    }

    
    @Resource
    public void setJaxbHelper(JaxbHelper aJaxbHelper) 
    {
        this.jaxbHelper = aJaxbHelper;
    }
    
}
