/********************************************************************
 * 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.constants.DelimeterConstants;
import gov.va.med.fw.hl7.segment.MSH;
import gov.va.med.fw.util.builder.BuilderException;

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

/**
 * Class to build the MSH segment.
 * 
 * @author Alex Yoon
 * @version 1.0
 */
public class MSHBuilder extends AbstractSegmentBuilder {
    
    /**
    * An instance of serialVersionUID 
    */
   private static final long serialVersionUID = 7256918937856239443L;
   
   private String processingId; 
    
   private String headerSendingFacility;
   
    public MSHBuilder() {
        super();
    }

    /**
     * @return Returns the processingId.
     */
    public String getProcessingId()
    {
        return processingId;
    }
    /**
     * @param processingId The processingId to set.
     */
    public void setProcessingId(String processingId)
    {
        this.processingId = processingId;
    }
    
    public String getHeaderSendingFacility() {
        return headerSendingFacility;
    }

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

    /**
     * Method to build the MSH segment.
     * 
     * @param metaData
     *           The parameter object used to build the a MSH segment.
     * @return The MSH segment.
     */
    public Object build(MSHMetaData metaData ) throws BuilderException {
        if (metaData == null) {
            throw new BuilderException("Invalid input parameter to build a segment");
        }
        
        MSH segment = new MSH();
        
        try {
            //Get Creation Datetime
            Date creationDatetime = metaData.getCreationDatetime();
            if (creationDatetime == null) {
                creationDatetime = Calendar.getInstance().getTime();
            }
            
            //Get Application ACK Type
            String applicationACKType = metaData.getApplicationACKType();
            if (applicationACKType == null || applicationACKType == "") {
                applicationACKType = HL7Constants.APPLICATION_ACK_TYPE_AL;
            }
            
            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.setMessageType( getInternalMessageType(metaData.getMessageType()) );
            segment.setControlID( metaData.getControlID() );
            segment.setProcessingID(processingId);
            segment.setVersionID( HL7Constants.VERSION_ID );
            segment.setAcceptAckType( HL7Constants.ACCEPT_ACK_TYPE );
            segment.setApplicationAckType( applicationACKType );
            segment.setCountryCode( HL7Constants.HEADER_COUNTRY );
        }
        catch (Exception e) {
            throw new BuilderException( "Failed to build MSH Segment due to an exception ", e);
        }
        
        return segment;
    }
    
    /**
     * Return the internal message type. The HL7 message type can differ from
     * internal message type.
     * 
     * @param messageType
     *           The HL7 message type.
     * @return The internal message type.
     */
    private String getInternalMessageType(String messageType) {
        String internalMessageType = null;
        
        if (messageType != null) {
            //Take care of messageType
            if (messageType.length() <= 3) {
                internalMessageType = messageType;
            }
            else {
                internalMessageType = messageType.substring(0, 3)
                + DelimeterConstants.DEFAULT_COMPONENT_DELIMITER
                + messageType.substring(3);
            }
        }
        
        return internalMessageType;
    }
}