package gov.va.med.esr.messaging.parser;

import java.util.Iterator;
import java.util.List;

import gov.va.med.esr.common.builder.entity.CombatEpisodeMetaData;
import gov.va.med.esr.common.builder.entity.EntityBuilder;
import gov.va.med.esr.common.builder.entity.MilitaryServiceMetaData;
import gov.va.med.esr.common.builder.entity.PersonMetaData;
import gov.va.med.esr.common.builder.entity.metaData.CombatEpisodeMetaDataFromZMH;
import gov.va.med.esr.common.builder.entity.metaData.MetaDataConstants;
import gov.va.med.esr.common.builder.entity.metaData.MilitaryServiceMetaDataFromZEL;
import gov.va.med.esr.common.builder.entity.metaData.PersonMetaDataFromPID;
import gov.va.med.esr.common.model.ee.CombatEpisode;
import gov.va.med.esr.common.model.ee.MilitaryService;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.fw.hl7.InvalidMessageException;
import gov.va.med.fw.hl7.Message;
import gov.va.med.fw.hl7.constants.SegmentConstants;
import gov.va.med.fw.hl7.segment.MSH;
import gov.va.med.fw.hl7.segment.PID;
import gov.va.med.fw.hl7.segment.ZEL;
import gov.va.med.fw.hl7.segment.ZMH;
import gov.va.med.fw.util.builder.Builder;
import gov.va.med.fw.util.builder.BuilderException;

public class K21Parser extends EntityBuilder {
    
    private static final long serialVersionUID = -6746553846341761472L;
    
    private Builder militaryServiceBuilder;
    
    private Builder personBuilder;
    
    private Builder combatEpisodeBuilder;
    
    public K21Parser()
    {
        super();
    }

    public Builder getCombatEpisodeBuilder() {
        return combatEpisodeBuilder;
    }

    public void setCombatEpisodeBuilder(Builder combatEpisodeBuilder) {
        this.combatEpisodeBuilder = combatEpisodeBuilder;
    }

    public Builder getMilitaryServiceBuilder() {
        return militaryServiceBuilder;
    }

    public void setMilitaryServiceBuilder(Builder militaryServiceBuilder) {
        this.militaryServiceBuilder = militaryServiceBuilder;
    }

    public Builder getPersonBuilder() {
        return personBuilder;
    }

    public void setPersonBuilder(Builder personBuilder) {
        this.personBuilder = personBuilder;
    }
    
    public Person build(Person input, Message message) throws BuilderException
    {
        try
        {
            Person person = this.buildPerson(input, message);

            person.setMilitaryService(this.buildMilitaryService(person
                    .getMilitaryService(), message));           
            
            this.buildCombatEpisodes(person, message);
            
            return person;
        } catch (InvalidMessageException e)
        {
            throw new BuilderException(e);
        }
    }
    
    private Person buildPerson(Person input, Message message)
    throws BuilderException, InvalidMessageException
    {

        PersonMetaData metaData = new PersonMetaDataFromPID((PID) message
                .getSegment(SegmentConstants.PID), null, null, null, (ZEL) message
                .getSegment(SegmentConstants.ZEL), (MSH) message
                .getSegment(SegmentConstants.MSH), message
                .getSegments(SegmentConstants.ZMH), null);
        metaData.setEntity(input);

        return this.buildPerson(metaData);
    }
    
    private Person buildPerson(PersonMetaData metaData) throws BuilderException
    {
        return (Person) this.personBuilder.build(metaData);
    }
    
    private MilitaryService buildMilitaryService(MilitaryService input,
            Message message) throws BuilderException, InvalidMessageException
    {
        MilitaryServiceMetaData metaData = new MilitaryServiceMetaDataFromZEL(
                (MSH) message.getSegment(SegmentConstants.MSH), (ZEL) message
                        .getSegment(SegmentConstants.ZEL), null, null, message
                        .getSegments(SegmentConstants.ZMH));
        metaData.setEntity(input);

        return this.buildMilitaryService(metaData);
    }
    
    private MilitaryService buildMilitaryService(
            MilitaryServiceMetaData metaData) throws BuilderException
    {
        return (MilitaryService) this.militaryServiceBuilder.build(metaData);
    }
    
    /**
     * Build Combat Episodes for OEF/OIF data
     * @param input
     * @param message
     * @throws BuilderException
     * @throws InvalidMessageException
     */
    private void buildCombatEpisodes(Person input, Message message)
            throws BuilderException, InvalidMessageException
    {
        List zmhs = message.getSegments(SegmentConstants.ZMH);
        MilitaryService ms = input.getMilitaryService();
        //remove all existing combat episodes
        ms.removeAllCombatEpisodes();
        
        if (zmhs != null && zmhs.size() > 0) {
            for (int index=0; index < zmhs.size(); index++){
                ZMH zmh = (ZMH) zmhs.get(index);
                if (MetaDataConstants.OEF_OIF_EPISODE.equals(zmh.getMilitaryHistoryType()))
                {
                    //process the segment for OEF/OIF
                    CombatEpisodeMetaData metaData = new CombatEpisodeMetaDataFromZMH(zmh);
                    CombatEpisode combatEpisode = (CombatEpisode)
                        getCombatEpisodeBuilder().build(metaData);
                    //build combat episode
                    Boolean shouldAdd = Boolean.TRUE; 
                    if (combatEpisode != null && shouldAdd.booleanValue()){
                        ms.addCombatEpisode(combatEpisode);
                    }                   
                }
            }
        }   
    }
    

}
