package gov.va.med.esr.messaging.builder.message;

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

import gov.va.med.esr.common.model.lookup.MessageType;
import gov.va.med.esr.common.model.messaging.SiteIdentity;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.messaging.constants.HL7Constants;
import gov.va.med.esr.service.trigger.IncomeYearTriggerEvent;
import gov.va.med.esr.service.trigger.PersonTriggerEvent;

import gov.va.med.fw.hl7.InvalidMessageException;
import gov.va.med.fw.hl7.Message;
import gov.va.med.fw.hl7.segment.ZDP;
import gov.va.med.fw.hl7.segment.ZIC;
import gov.va.med.fw.hl7.segment.ZIR;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.util.builder.BuilderException;

/**
 * Builds the outbound ORUZ06 Means Test Data(Means test signature)message.
 * 
 * @author Rajiv Patnaik Created on Jan 17, 2006
 * @version 1.0
 * 
 * Copyright © 2005 VHA. All rights reserved
 */
public class ORUZ06Builder extends AbstractMessageBuilder
{
    /**
    * An instance of serialVersionUID 
    */
   private static final long serialVersionUID = -483715285851656127L;
   private ZMTBuilder zmtBuilder;
   private ZICBuilder zicBuilder;
   private ZIRBuilder zirBuilder;
   private ZDPBuilder zdpBuilder;
   private ZIVBuilder zivBuilder;   
   

    public ORUZ06Builder()
    {
        super();
    }

    /**
     * @return Returns the zmtBuilder.
     */
    public ZMTBuilder getZmtBuilder()
    {
        return zmtBuilder;
    }

    /**
     * @param zmtBuilder
     *            The zmtBuilder to set.
     */
    public void setZmtBuilder(ZMTBuilder zmtBuilder)
    {
        this.zmtBuilder = zmtBuilder;
    }

    /**
     * Method to build the ORUZ06 message.
     * 
     * @param object
     *            array The person who is source of message content.
     * @param siteIdentity
     *            The siteIdentity that is a destination of message.
     * @return The ORUZ06 message.
     * @throws BuilderException
     */
    public Message build(Object[] args) throws BuilderException
    {
        return this.build((Person) args[0], (SiteIdentity) args[1],
                (args[3] == null ? null : (PersonTriggerEvent) args[3]));
    }

    /**
     * Method to build the ORUZ06 message.
     * 
     * @param The
     *            person who is source of message content.
     * @param siteIdentity
     *            The siteIdentity that is a destination of message.
     * @return The ORUZ06 message.
     * @throws BuilderException
     */
    public Message build(Person person, SiteIdentity siteIdentity,
            PersonTriggerEvent triggerEvent) throws BuilderException
    {
    	if (person == null || siteIdentity == null || triggerEvent == null 
                || !(triggerEvent instanceof IncomeYearTriggerEvent))
        {
            throw new BuilderException(
                    "Invalid input parameters to build an object");
        }        
 
        IncomeYearTriggerEvent incomeYearEvent = (IncomeYearTriggerEvent) triggerEvent;

        if (super.logger.isInfoEnabled())
        {
            super.logger.info("Building outbound ORUZ06");

            if (person.getEntityKey() != null)
            {
                super.logger.info("Person id = " + person.getEntityKey());
            }

            if (siteIdentity.getVaFacility() != null)
            {
                super.logger.info("Station Number = "
                        + siteIdentity.getVaFacility().getStationNumber());
            }
        }

        Message message = null;
        List segments = new ArrayList();

        try
        {
            segments.add(super.buildMSHSegment(siteIdentity,
                    HL7Constants.ORUZ06));
            
            segments.add(super.buildPIDSegment(person, siteIdentity)); 
            
            buildEmptyReqSegments(segments);
            
            //For ORUZ06, the ZMT Builder returns a List containing 1 ZMT
            // segment
            ZMTMetaData zmtMetadata = new ZMTMetaData(person,
                    getLookupService().getMessageTypeByCode(
                            MessageType.CODE_ORUZ06_TO_SITE.getName()));
            zmtMetadata.setIncomeYear(incomeYearEvent.getIncomeYear());
            zmtMetadata.setAction(incomeYearEvent.getActionCode());
            zmtMetadata.setType(incomeYearEvent.getType());  
            zmtMetadata.setDeletedIncomeTest(incomeYearEvent.getDeletedIncomeTest());

            List zmtSegments = (List) this.zmtBuilder.build(zmtMetadata);
            segments.add(zmtSegments.iterator().next());
            
            segments.add(this.zivBuilder.build(triggerEvent));

            message = new Message(segments, HL7Constants.ORUZ06,true);
            
        } catch (ServiceException se)
        {
            throw new BuilderException(
                    "Failed to build ORUZ06 message due to a exception ", se);
        } catch (InvalidMessageException me)
        {
            throw new BuilderException(
                    "Failed to build ORUZ06 message due to an segment exception ",
                    me);
        }

        super.logger.info("Built outbound ORUZ06 "); 

        if (super.logger.isDebugEnabled())
        {
            super.logger.debug("ORUZ06 Message = " + message.getMessageData());
        }

        return message;
    }
    
    //creates the required empty segments for Z06
    private List buildEmptyReqSegments(List segments){
    	
    	ZIC vetSegzic = new ZIC();
        vetSegzic.setSetID("1");
        segments.add(vetSegzic);
        
        ZIR vetSegzir = new ZIR();
        vetSegzir.setSetID("1");
        segments.add(vetSegzir);
        
        ZDP spoSegzdp = new ZDP();
        spoSegzdp.setSetID("1");
        segments.add(spoSegzdp);
        
        ZIC spoSegzic = new ZIC();
        spoSegzic.setSetID("1");
        segments.add(spoSegzic);
        
        ZIR spoSegzir = new ZIR();
        spoSegzir.setSetID("1");
        segments.add(spoSegzir);
    	
    	return segments;
    	
    }

	public ZDPBuilder getZdpBuilder() {
		return zdpBuilder;
	}

	public void setZdpBuilder(ZDPBuilder zdpBuilder) {
		this.zdpBuilder = zdpBuilder;
	}

	public ZICBuilder getZicBuilder() {
		return zicBuilder;
	}

	public void setZicBuilder(ZICBuilder zicBuilder) {
		this.zicBuilder = zicBuilder;
	}

	public ZIRBuilder getZirBuilder() {
		return zirBuilder;
	}

	public void setZirBuilder(ZIRBuilder zirBuilder) {
		this.zirBuilder = zirBuilder;
	}

	public ZIVBuilder getZivBuilder() {
		return zivBuilder;
	}

	public void setZivBuilder(ZIVBuilder zivBuilder) {
		this.zivBuilder = zivBuilder;
	}

	
}