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

//Java Classes
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

//Framework classes
import gov.va.med.fw.hl7.InvalidMessageException;
import gov.va.med.fw.hl7.InvalidSegmentException;
import gov.va.med.fw.hl7.Message;
import gov.va.med.fw.util.builder.BuilderException;
import gov.va.med.fw.hl7.builder.HL7MetaData;
import gov.va.med.fw.hl7.segment.MFI;
import gov.va.med.fw.hl7.segment.MFE;
import gov.va.med.fw.model.AbstractEntity;

//ESR Classes
import gov.va.med.esr.messaging.constants.HL7Constants;
import gov.va.med.esr.common.model.ee.EGTSetting;
import gov.va.med.esr.common.model.lookup.VAFacility;

/**
 * Class to build the MFNZEG message from a EGTSetting object.
 * 
 * @author Alex Yoon
 * @version 1.0
 */
public class MFNZEGBuilder extends AbstractMessageBuilder
{
    /**
    * An instance of serialVersionUID 
    */
   private static final long serialVersionUID = 4204626997018929129L;

   private MFIBuilder mfiBuilder;

    private MFEBuilder mfeBuilder;

    private ZEGBuilder zegBuilder;

    private static final String MASTER_FILE_ID_SEGMENT = "ZEG";

    private static final String MASTER_FILE_ID_SEGMENT_NAME = "ENROLLMENT GROUP THRESHOLD UPDATE";

    private static final String MASTER_FILE_ID_CODING_SYSTEM = "HL70175";

    private static final String MASTER_FILE_ID_FILE_NUMBER = "742060";

    private static final String MASTER_FILE_ID_FILE_NAME = "ENROLLMENT GROUP THRESHOLD";

    private static final String FILE_LEVEL_EVENT_CODE = "REP";

    private static final String RESPONSE_LEVEL_CODE = "AL";

    private static final String RECORD_LEVEL_EVENT_CODE = "MAD";

    private static final String PRIMARY_KEY_VALUE_FILE_NAME = MASTER_FILE_ID_FILE_NAME;

    private static final String PRIMARY_KEY_VALUE_CODING_SYSTEM = "VA0017";

    /**
     * Default constructor
     */
    public MFNZEGBuilder()
    {
        super();
    }

    public MFIBuilder getMfiBuilder()
    {
        return this.mfiBuilder;
    }

    public void setMfiBuilder(MFIBuilder mfiBuilder)
    {
        this.mfiBuilder = mfiBuilder;
    }

    public MFEBuilder getMfeBuilder()
    {
        return this.mfeBuilder;
    }

    public void setMfeBuilder(MFEBuilder mfeBuilder)
    {
        this.mfeBuilder = mfeBuilder;
    }

    public ZEGBuilder getZegBuilder()
    {
        return this.zegBuilder;
    }

    public void setZegBuilder(ZEGBuilder zegBuilder)
    {
        this.zegBuilder = zegBuilder;
    }

    /**
     * Method to build the MFNZEG message.
     * 
     * @param object
     *            array The EGTSetting that is source of message content.
     * @param VAFacility
     *            The VAFacility that is a destination of message.
     * @return The MFNZEG message.
     * @throws BuilderException
     */
    public Message build(Object[] args) throws BuilderException
    {
        return this.build((EGTSetting) args[0], (VAFacility) args[1]);
    }

    /**
     * Method to build the MFNZEG message.
     * 
     * @param The
     *            EGTSetting that is source of message content.
     * @param VAFacility
     *            The VAFacility that is a destination of message.
     * @return The MFNZEG message.
     * @throws BuilderException
     */
    public Message build(EGTSetting egt, VAFacility site)
            throws BuilderException
    {
        Message message = null;
        List segments = new ArrayList();

        try
        {
            HL7MetaData metaData = new HL7MetaData(egt);

            segments.add(super.buildMSHSegment(site, HL7Constants.MFNZEG));
            segments.add(buildMFISegment());
            segments.add(buildMFESegment(egt));
            segments.add(this.zegBuilder.build(metaData));

            message = new Message(segments, HL7Constants.MFNZEG);

            if (super.logger.isInfoEnabled())
            {
                super.logger.info("Built outbound MFNZEG ID "
                        + message.getMessageID() + " Station Number = "
                        + site.getStationNumber());
            }
            
        } catch (InvalidSegmentException me)
        {
            throw new BuilderException(
                    "Failed to build MFNZEG message due to an segment exception ",
                    me);
        } catch (InvalidMessageException me)
        {
            throw new BuilderException(
                    "Failed to build MFNZEG message due to an exception ", me);
        }


        return message;
    }

    /**
     * Method to build the MFI segment.
     * 
     * @return The MFI segment.
     * @throws BuilderException
     */
    private MFI buildMFISegment() throws BuilderException
    {
        MFI segment = null;

        try
        {
            MFIMetaData metaData = new MFIMetaData((AbstractEntity) null);

            metaData.setMasterFileIDSegment(MASTER_FILE_ID_SEGMENT);
            metaData.setMasterFileIDSegmentName(MASTER_FILE_ID_SEGMENT_NAME);
            metaData.setMasterFileIDCodingSystem(MASTER_FILE_ID_CODING_SYSTEM);
            metaData.setMasterFileIDFileNumbert(MASTER_FILE_ID_FILE_NUMBER);
            metaData.setMasterFileIDFileName(MASTER_FILE_ID_FILE_NAME);
            metaData.setFileLevelEventCode(FILE_LEVEL_EVENT_CODE);
            metaData.setEnteredDate(Calendar.getInstance().getTime());
            metaData.setResponseLevelCode(RESPONSE_LEVEL_CODE);

            //Get segment through its builder
            segment = (MFI) (this.mfiBuilder.build(metaData));
        } catch (Exception e)
        {
            throw new BuilderException(
                    "Failed to build MFI Segment due to an exception ", e);
        }

        return segment;
    }

    /**
     * Method to build the MFE segment.
     * 
     * @param egt
     *            The EGTSetting that is source for MFE segment content.
     * @return The MFE segment.
     * @throws BuilderException
     */
    private MFE buildMFESegment(EGTSetting egt) throws BuilderException
    {
        MFE segment = null;

        try
        {
            MFEMetaData metaData = new MFEMetaData((AbstractEntity) null);

            metaData.setRecordLeveEventCode(RECORD_LEVEL_EVENT_CODE);
            
            metaData.setMfnControlID(egt.getEntityKey() != null ? ((Object) egt
                    .getEntityKey().getKeyValue()).toString() : null);
            
            metaData.setEffectiveDate(egt.getEffectiveDate());
            
            metaData.setPrimaryKeyValueEffectiveDate(egt.getEffectiveDate());
            
            metaData.setPrimaryKeyValueFileName(PRIMARY_KEY_VALUE_FILE_NAME);
            
            metaData
                    .setPrimaryKeyValueCodingSystem(PRIMARY_KEY_VALUE_CODING_SYSTEM);

            //Get segment through its builder
            segment = (MFE) (this.mfeBuilder.build(metaData));
        
        } catch (Exception e)
        {
            throw new BuilderException(
                    "Failed to build MFE Segment due to an exception ", e);
        }

        return segment;
    }
}