/**
 * 
 */


package gov.va.med.cds.response.vhim400;


import gov.va.med.cds.exception.ErrorCodeEnum;
import gov.va.med.cds.exceptionframework.ExceptionInfo;
import gov.va.med.cds.junit.runners.Suite;
import gov.va.med.cds.junit.runners.SuiteAwareRunner;
import gov.va.med.cds.request.RequestProcessingException;
import gov.va.med.cds.request.ValidationException;
import gov.va.med.cds.request.ErrorSectionHelperInterface.ErrorType;
import gov.va.med.cds.response.vhim400.FlatErrorSectionHelper;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;


/**
 * @author DNS   SOVAR
 *
 */
@RunWith( SuiteAwareRunner.class )
public class FlatErrorSectionHelperTest
{
    String EMPTY_CLINICAL_DATA = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><clinicaldata:ClinicalData xmlns:clinicaldata=\"Clinicaldata\"><templateId>AllergiesRead40010</templateId><requestId>aRequestId</requestId></clinicaldata:ClinicalData>";
    String ERROR_SECTION = "<errorSection><fatalErrors><errorId>requestId</errorId><exception>gov.va.med.cds.request.ValidationException</exception><exceptionMessage>OPERATION_NOT_SUPPORTED</exceptionMessage><errorCode>ACCESSOR_ENTRYPOINT_INVALID</errorCode><displayMessage>clientMessage</displayMessage></fatalErrors></errorSection>";


    @Test
    @Suite( groups = { "checkintest" } )
    public void testBuildErrorSection_NoErrorSection( )
        throws Exception
    {
        // Create Exception Information 
        ExceptionInfo exceptionInfoFatal = new ExceptionInfo();
        exceptionInfoFatal.setClientMessage( "clientMessage" );
        exceptionInfoFatal.setErrorCode( ErrorCodeEnum.CANNOT_PARSE_DATE );
        exceptionInfoFatal.setException( new ValidationException( ErrorCodeEnum.OPERATION_NOT_SUPPORTED ) );
        exceptionInfoFatal.setExceptionMessage( "exceptionMessage" );

        FlatErrorSectionHelper errorSectionHelper = new FlatErrorSectionHelper();

        Document clinicalData = DocumentHelper.parseText( EMPTY_CLINICAL_DATA );
        errorSectionHelper.buildErrorSection( clinicalData, exceptionInfoFatal, "requestId" );
        Assert.assertTrue( clinicalData.selectNodes( "/ClinicalData/errorSection/*" ).size() == 1 );
        Assert.assertTrue( clinicalData.selectNodes( "/ClinicalData/errorSection/fatalErrors" ).size() == 1 );
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testBuildErrorSection_ExistingSection( )
        throws Exception
    {
        ExceptionInfo exceptionInfoWarning = new ExceptionInfo();
        exceptionInfoWarning.setClientMessage( "clientMessage2" );
        exceptionInfoWarning.setErrorCode( ErrorCodeEnum.READ_REQUEST_UNKNOWN_FILTER );
        exceptionInfoWarning.setException( new ValidationException( ErrorCodeEnum.CANNOT_FIND_FILTER_VALIDATOR, "Something went wrong" ) );
        exceptionInfoWarning.setExceptionMessage( "exceptionMessage" );

        FlatErrorSectionHelper errorSectionHelper = new FlatErrorSectionHelper();

        String clinicalDataWithErrorSection = EMPTY_CLINICAL_DATA.replaceFirst( "</clinicaldata:ClinicalData>", ERROR_SECTION ).concat( "</clinicaldata:ClinicalData>" );
        Document clinicalData = DocumentHelper.parseText( clinicalDataWithErrorSection );
        errorSectionHelper.buildErrorSection( clinicalData, exceptionInfoWarning, "requestId" );
        Assert.assertTrue( clinicalData.selectNodes( "/ClinicalData/errorSection/*" ).size() == 2 );
        Assert.assertTrue( clinicalData.selectNodes( "/ClinicalData/errorSection/fatalErrors" ).size() == 1 );
        Assert.assertTrue( clinicalData.selectNodes( "/ClinicalData/errorSection/warnings" ).size() == 1 );

    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testBuildErrorSection_MultiSection( )
        throws Exception
    {
        ExceptionInfo exceptionInfoWarning = new ExceptionInfo();
        exceptionInfoWarning.setClientMessage( "clientMessage2" );
        exceptionInfoWarning.setErrorCode( ErrorCodeEnum.READ_REQUEST_UNKNOWN_FILTER );
        exceptionInfoWarning.setException( new ValidationException( ErrorCodeEnum.CANNOT_FIND_FILTER_VALIDATOR, new RuntimeException(), "Something went wrong" ) );
        exceptionInfoWarning.setExceptionMessage( "exceptionMessage" );

        FlatErrorSectionHelper errorSectionHelper = new FlatErrorSectionHelper();
        String clinicalDataWithErrorSection = EMPTY_CLINICAL_DATA.replaceFirst( "</clinicaldata:ClinicalData>", ERROR_SECTION ).concat( "</clinicaldata:ClinicalData>" );
        Document clinicalData = DocumentHelper.parseText( clinicalDataWithErrorSection );

        errorSectionHelper.buildErrorSection( clinicalData, exceptionInfoWarning, "requestId" );
        Assert.assertTrue( clinicalData.selectNodes( "/ClinicalData/errorSection/*" ).size() == 2 );

        ExceptionInfo exceptionInfoError = new ExceptionInfo();
        exceptionInfoError.setClientMessage( "clientMessage3" );
        exceptionInfoError.setErrorCode( ErrorCodeEnum.ERROR_VALIDATIING_XML_AGAINST_COMPILED_SCHEMA );
        exceptionInfoError.setException( new RequestProcessingException( ErrorCodeEnum.READ_REQUEST_TEMPLATE_ID_NULL, "Boom" ) );
        errorSectionHelper.buildErrorSection( clinicalData, exceptionInfoError, "requestId" );
        
        Assert.assertTrue( errorSectionHelper.getErrorCount( ErrorType.ALL, clinicalData ) == 3 );
        Assert.assertTrue( errorSectionHelper.getErrorCount( ErrorType.WARNING, clinicalData ) == 1 );
        Assert.assertTrue( errorSectionHelper.getErrorCount( ErrorType.ERROR, clinicalData ) == 1 );
        Assert.assertTrue( errorSectionHelper.getErrorCount( ErrorType.FATAL, clinicalData ) == 1 );

    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testGetErrorCount( )
        throws Exception
    {

    }

}
