/**
 * 
 */


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


import gov.va.med.cds.clinicaldata.DomainEntryPoint;
import gov.va.med.cds.exception.ErrorCodeEnum;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.springframework.beans.factory.annotation.Required;


/**
 * @author DNS   egberb
 *
 */
public class CdsResponse1ClinicalDataResponse
    extends
        ConfigurableClinicalDataResponse
{
    private Map<String, Set<DomainEntryPoint>> templateIdToDomainEntryPointListMap = null;
    
    private String statusElementName = null;


    public CdsResponse1ClinicalDataResponse( String patientElementPath, String clinicalRootPath, String errorResponseTemplateId )
    {
        super( patientElementPath, clinicalRootPath, errorResponseTemplateId );
    }


    @Override
    public Element buildRecordIdentifierElement( String recordIdentifier, Element clinicalData )
    {
        Element identifierElement = DocumentHelper.createElement( "identifier" );

        if ( recordIdentifier != null )
        {
            identifierElement.add( DocumentHelper.createElement( "recordIdentifier" ) );
            identifierElement.element( "recordIdentifier" ).add( DocumentHelper.createElement( "identity" ) );
            identifierElement.element( "recordIdentifier" ).element( "identity" ).setText( recordIdentifier );
        }

        Node documentIdentifier = clinicalData.element( "documentIdentifier" );
        if ( documentIdentifier == null )
        {
            // because the document identifier is requred by the create schemas, we do not expect that 
            // we will ever hit the following line of code.
            throw new IllegalArgumentException( "Required document identifier element not present in create document." );
        }
        
        identifierElement.add( ( Node )documentIdentifier.clone() );
        
        Element statusElement = clinicalData.element( statusElementName );
        if ( statusElement != null )
        {
        	String status = statusElement.getText();
        	statusElement = DocumentHelper.createElement("status");
        	statusElement.setText(status);
        	
        	identifierElement.add(statusElement);
        }

        return identifierElement;
    }


    @Override
    public Document buildErrorResponse( String templateId, String requestId, Document writeResultDocument, Document clinicalDataDocument )
    {
        List<String> identifiers = null;
        if ( clinicalDataDocument != null )
        {
            identifiers = this.getDocumentIdentifiers( templateId, clinicalDataDocument );
        }

        if ( identifiers != null && identifiers.size() > 0 )
        {
            Node displayMessageNode = writeResultDocument.selectSingleNode( "//displayMessage" );
            if ( displayMessageNode != null )
            {
                String displayMessageText = displayMessageNode.getText();
                displayMessageText = String.format( "%s Could not process document(s): %s", displayMessageText, identifiers.toString() );
                displayMessageNode.setText( displayMessageText );
            }
        }
        return writeResultDocument;

    }


    private List<String> getDocumentIdentifiers( String templateId, Document clinicalDataDocument )
    {
        List<String> recordIdentifiers = new ArrayList<String>();
        if ( this.templateIdToDomainEntryPointListMap != null )
        {
            Set<DomainEntryPoint> domainEntryPoints = this.templateIdToDomainEntryPointListMap.get( templateId );

            if ( domainEntryPoints == null )
            {
                throw new RuntimeException( ErrorCodeEnum.WRITE_REQUEST_SIMPLE_INVALID_TEMPLATE_ID.getClientMessage() );
            }

            Element documentRoot = clinicalDataDocument.getRootElement();
            Element patientElement = documentRoot.element( "patient" );

            for ( DomainEntryPoint domainEntryPoint : domainEntryPoints )
            {
                List<Element> clinicalRecords = domainEntryPoint.getClinicalRecords( patientElement );

                if ( clinicalRecords != null && clinicalRecords.size() > 0 )
                {
                    for ( Element clinicalRecord : clinicalRecords )
                    {
                        Node documentIdentifier = clinicalRecord.selectSingleNode( "//documentIdentifier/identity" );
                        if ( documentIdentifier != null )
                        {
                            String documentId = documentIdentifier.getText();
                            if ( documentId != null && documentId.length() > 0 )
                            {
                                recordIdentifiers.add( documentId );
                            }
                        }
                    }
                }
            }
        }
        return recordIdentifiers;
    }


    @Required
    public void setTemplateIdToDomainEntryPointListMap( Map<String, Set<DomainEntryPoint>> templateIdToDomainEntryPointListMap )
    {
        this.templateIdToDomainEntryPointListMap = templateIdToDomainEntryPointListMap;
    }
    
    @Resource
    public void setStatusElementName(String statusElementName) {
		this.statusElementName = statusElementName;
	}

}
