/********************************************************************
 * Copyright © 2004 EDS. All rights reserved
 ********************************************************************/
//Package
package gov.va.med.esr.messaging.builder.message;

//Java Classes
import java.util.Calendar;
import java.util.Date;

import gov.va.med.fw.hl7.BatchMessage;
import gov.va.med.fw.hl7.constants.DelimeterConstants;
import gov.va.med.fw.hl7.segment.BHS;
import gov.va.med.fw.util.builder.BuilderException;

import gov.va.med.esr.messaging.constants.HL7Constants;


/**
 * The class that builds the BHS segment for a message.
 * 
 * @author Alex Yoon
 * @version 1.0
 */
public class BHSBuilder extends AbstractSegmentBuilder {
    
    /**
    * An instance of serialVersionUID 
    */
   private static final long serialVersionUID = -6123435200458519578L;

   private String processingId;
   
   private String headerSendingFacility;   
    
    public static final String MESSAGE_ID_PREFIX = "A";
    
    
    public BHSBuilder() {
        super();
    }
    
    public String getHeaderSendingFacility() {
        return headerSendingFacility;
    }


    public void setHeaderSendingFacility(String headerSendingFacility) {
        this.headerSendingFacility = headerSendingFacility;
    }

    /**
     * @return Returns the processingId.
     */
    public String getProcessingId()
    {
        return processingId;
    }
    /**
     * @param processingId The processingId to set.
     */
    public void setProcessingId(String processingId)
    {
        this.processingId = processingId;
    }
    /**
     * The method that builds the segment based on a descriptor.
     * 
     * @param metaData
     *           The parameter object used to build a BHS segment.
     * @return The BHS Segment.
     */	
    public Object build( BHSMetaData metaData ) throws BuilderException {
        if (metaData == null) {
            throw new BuilderException("Invalid input parameter to build a segment");
        }
        
        BHS segment = new BHS();
        
        try {
            //Get Creation Datetime
            Date creationDatetime = metaData.getCreationDatetime();
            if (creationDatetime == null) {
                creationDatetime = Calendar.getInstance().getTime();
            }
            
            //Get Control ID
            //Get Reference Control ID - Only for ACK
            String controlID = null;
            String referenceControlID = null;
            
            if (HL7Constants.ACK.equals(metaData.getMessageType())) {
                BatchMessage message = metaData.getBatchMessage();
                if (message != null) {
                    referenceControlID = message.getMessageID();
                    controlID = MESSAGE_ID_PREFIX + referenceControlID;
                }
                else {
                    controlID = metaData.getControlID();
                }
            }
            else {
                controlID = metaData.getControlID();
            }
            
            segment.setEncodingCharacters(DelimeterConstants.DEFAULT_ENCODING_ELEMENT);
            
            segment.setSendingApplication(HL7Constants.HEADER_SENDING_APPLICATION);
            segment.setSendingFacility(getHeaderSendingFacility());           
            segment.setReceivingApplication( metaData.getReceivingApplication());
            segment.setReceivingFacility( metaData.getReceivingFacility() );
            segment.setCreationDate( DateFormatter.formatDateTime(creationDatetime).toString() );
            segment.setNameIDType( getNameIDType( metaData.getMessageType() ) );
            if(metaData.getComment() != null)
                segment.setComment( metaData.getComment() );
            segment.setControlID( controlID );
            if(referenceControlID != null)
                segment.setReferenceControlID(referenceControlID); 
        }
        catch( Exception e ) {
            throw new BuilderException( "Failed to build BHS Segment due to an exception ", e );
        } 
        
        return segment;
    }
    
    /**
     * Method that gets nameIDType.
     * 
     * @param messageType
     *           The type of message.
     * @return The nameIDType.
     */
    private String getNameIDType(String messageType) {
        String nameIDType = null;
        
        if (messageType != null) {
            //First Component is not used
            nameIDType = DelimeterConstants.DEFAULT_COMPONENT_DELIMITER
            + processingId
            + DelimeterConstants.DEFAULT_COMPONENT_DELIMITER;
            
            //Take care of messageType
            if (messageType != null) {
                if (messageType.length() <= 3) {
                    nameIDType += messageType;
                }
                else {
                    nameIDType += messageType.substring(0, 3)
                    + "|"
                    + messageType.substring(3);
                }
            }
            
            nameIDType += DelimeterConstants.DEFAULT_COMPONENT_DELIMITER
            + HL7Constants.VERSION_ID
            + DelimeterConstants.DEFAULT_COMPONENT_DELIMITER
            + HL7Constants.ACCEPT_ACK_TYPE
            + DelimeterConstants.DEFAULT_COMPONENT_DELIMITER;
            
            if (HL7Constants.ACK.equals(messageType)) {
                nameIDType += HL7Constants.APPLICATION_ACK_TYPE_NE;
            }
            else {
                nameIDType += HL7Constants.APPLICATION_ACK_TYPE_AL;
            }
        }
        
        return nameIDType;
    }
}
