

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


import gov.va.med.cds.exception.ResponseException;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Node;


public class ResponseErrorSectionExtractor
{
    private static Log logger = LogFactory.getLog( ResponseErrorSectionExtractor.class );
    private Document documentObj;
    private List<Node> nodeList;
    private List<Node> childNodeList;

    private List<String> severityList;


    public Document getDocument( String response )
    {
        Document docObj = null;
        try
        {
            docObj = DocumentHelper.parseText( response );
        }
        catch ( DocumentException e )
        {
            if ( logger.isErrorEnabled() )
            {
                logger.error( gov.va.med.cds.util.LogMessageUtil.buildMessage( null, null, "CDS",  String.format( "CDS response document could not be parsed: %s ", e.getMessage() ) ), e );
            }
        }
        return docObj;
    }


    @SuppressWarnings( "unchecked" )
    public String getErrorSection( String response )
    {
        documentObj = getDocument( response );
        nodeList = new ArrayList<Node>( documentObj.selectNodes( "//ClinicalData/errorSection/*" ) );

        StringBuilder errorMessage = new StringBuilder();
        if ( nodeList.size() > 0 )
        {
            errorMessage = new StringBuilder( "Unable to process message.  Following is a list of one or more exceptions encountered: " );

            int nodeQuantifier = 0;
            for ( String severity : severityList )
            {
                for ( Node node : nodeList )
                {
                    if ( severity.equalsIgnoreCase( node.getName() ) )
                    {
                        errorMessage.append( String.format( "ErrorSevirity : %s\t", node.getName() ) );
                        nodeQuantifier++ ;
                        childNodeList = new ArrayList<Node>( node.selectNodes( "//ClinicalData/errorSection/" + severity + "[" + nodeQuantifier
                                        + "]/*" ) );
                        for ( Node childNode : childNodeList )
                        {
                            if ( "errorCode".equalsIgnoreCase( childNode.getName() ) )
                            {
                                errorMessage.append( String.format( "ErrorCode : %s\t", childNode.getText() ) );
                            }
                            if ( "displayMessage".equalsIgnoreCase( childNode.getName() ) )
                            {
                                errorMessage.append( String.format( "DisplayMessage : %s\n", childNode.getText() ) );
                            }
                        }
                    }
                }
                nodeQuantifier = 0;
            }
        }
        return errorMessage.toString();
    }


    public void checkForErrorsInResponse( String response )
        throws ResponseException
    {
        String errorSection = getErrorSection( response );

        //throw an exception if response has any errors
        if ( errorSection.length() > 0 )
        {
            throw new ResponseException( errorSection );
        }
    }


    @Resource
    public void setSeverityList( List<String> severityList )
    {
        this.severityList = severityList;
    }
}
