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

import java.util.Iterator;
import java.util.Set;

import gov.va.med.esr.common.model.ee.ConflictExperience;
import gov.va.med.esr.common.model.ee.MilitaryService;
import gov.va.med.esr.common.model.ee.MilitaryServiceEpisode;
import gov.va.med.esr.common.model.ee.MilitaryServiceSiteRecord;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.builder.entity.metaData.MetaDataConstants;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
 * 
 * @author Rajiv Patnaik Created on Aug 8, 2005
 * @version 1.0
 * 
 * Copyright © 2005 VHA. All rights reserved
 */
public class ZMHTestDataValidator extends BaseSegmentsTestDataValidator
        implements XMLSegmentTagNameConstants
{

    public void validateZMH(Document document, Person person)
    {
        //Get the sending facility station no.
        String sendingFacilityStationNumber = getSendingFacilityStationNumber(document);

        MilitaryService militaryService = person.getMilitaryService();
        MilitaryServiceSiteRecord militaryServiceSiteRecord = null;
        Set militaryServiceEpisodes = null;
        Set conflictExperiences = null;
        if (militaryService != null)
        {
            militaryServiceSiteRecord = militaryService
                    .getMilitaryServiceSiteRecordsBySite(sendingFacilityStationNumber);
            if (militaryServiceSiteRecord != null)
            {
                militaryServiceEpisodes = militaryServiceSiteRecord
                        .getMilitaryServiceEpisodes();
                conflictExperiences = militaryServiceSiteRecord
                        .getConflictExperiences();
            }
        }
        NodeList nodeList = document.getElementsByTagName(ZMH);
        for (int i = 0; i < nodeList.getLength(); i++)
        {
            Element element = (Element) nodeList.item(i);

            String militaryHistoryType = getElement(element, ZMH_2);
            if (isCombatExperience(militaryHistoryType)
                    || isConflictExperience(militaryHistoryType))
            {
                validateConflictExperience(conflictExperiences, element);

            } else if (isMilitaryServiceEpisode(militaryHistoryType))
            {
                validateMilitaryServiceEpisode(militaryServiceEpisodes, element);
            }
        }
    }

    /**
     * @param conflictExperiences
     * @param element
     */
    private void validateMilitaryServiceEpisode(Set militaryServiceEpisodes,
            Element element)
    {
        String serviceBranchFromMsg = getSubElementData(element, ZMH_3, CE_1);
        String serviceNumberFromMsg = getSubElementData(element, ZMH_3, CE_2);
        String dischargeTypeFromMsg = getSubElementData(element, ZMH_3, CE_3);

        //ZMH.4 contains<dr.1>which contains<ts.1>
        Element dr1Element = getSubElement(element, ZMH_4, DR_1);
        String startDateFromMsg = getElement(dr1Element, TS_1);

        Element dr2Element = getSubElement(element, ZMH_4, DR_2);
        String endDateFromMsg = getElement(dr2Element, TS_1);

        validateNotNull(serviceBranchFromMsg, militaryServiceEpisodes,
                "MilitaryServiceEpisodes is null");

        for (Iterator iter = militaryServiceEpisodes.iterator(); iter.hasNext();)
        {
            MilitaryServiceEpisode serviceEpisode = (MilitaryServiceEpisode) iter
                    .next();
            String serviceNumber = serviceEpisode.getServiceNumber();
            //validate the ZMH segment passed in
            if (serviceNumberFromMsg.equals(serviceNumber))
            {
                assertLookupDescription(serviceEpisode.getDischargeType(),
                        dischargeTypeFromMsg, "DischargeType does not match");
                assertLookupDescription(serviceEpisode.getServiceBranch(),
                        serviceBranchFromMsg, "ServiceBranch does not match");

                validateImpreciseDate(serviceEpisode.getStartDate(),
                        startDateFromMsg, "serviceEpisodeStartDate is null",
                        "serviceEpisodeStartDate does not match");
                validateImpreciseDate(serviceEpisode.getEndDate(),
                        endDateFromMsg, "serviceEpisodeEndDate is null",
                        "serviceEpisodeEndDate does not match");
            }
        }

    }

    /**
     * @param conflictExperiences
     * @param element
     */
    private void validateConflictExperience(Set conflictExperiences,
            Element element)
    {
        String militaryHistoryType = getElement(element, ZMH_2);

        //ZMH.4 contains<dr.1>which contains<ts.1>
        Element dr1Element = getSubElement(element, ZMH_4, DR_1);
        String startDateFromMsg = getSubElementData(dr1Element, DR_1, TS_1);

        Element dr2Element = getSubElement(element, ZMH_4, DR_2);
        String endDateFromMsg = getSubElementData(dr2Element, DR_2, TS_1);

        validateNotNull(militaryHistoryType, conflictExperiences,
                "Conflict Experiences is null");

        for (Iterator iter = conflictExperiences.iterator(); iter.hasNext();)
        {
            ConflictExperience conflictExperience = (ConflictExperience) iter
                    .next();
            String conflictLocationDesc = conflictExperience
                    .getConflictLocation().getDescription();
            //validate the ZMH segment passed in
            if (militaryHistoryType.equals(conflictLocationDesc))
            {
                validateImpreciseDate(conflictExperience.getStartDate(),
                        startDateFromMsg, "ConflictStartDate is null",
                        "ConflictStartDate does not match");
                validateImpreciseDate(conflictExperience.getEndDate(), endDateFromMsg,
                        "ConflictEndDate is null",
                        "ConflictStartDate does not match");
            }
        }
    }

    private boolean isCombatExperience(String type)
    {
        return (MetaDataConstants.COMBAT_EXPERIENCE.equals(type));
    }

    private boolean isConflictExperience(String type)
    {
        return (MetaDataConstants.CONFLICT_EXPERIENCE_VIET.equals(type)
                || MetaDataConstants.CONFLICT_EXPERIENCE_LEBA.equals(type)
                || MetaDataConstants.GREN_CONFLICT_EXPERIENCE.equals(type)
                || MetaDataConstants.CONFLICT_EXPERIENCE_PANA.equals(type)
                || MetaDataConstants.CONFLICT_EXPERIENCE_GULF.equals(type)
                || MetaDataConstants.CONFLICT_EXPERIENCE_SOMA.equals(type) || MetaDataConstants.CONFLICT_EXPERIENCE_YUGO
                .equals(type));
    }

    private boolean isMilitaryServiceEpisode(String type)
    {
        return (MetaDataConstants.MILITARY_EPISODE_SL.equals(type)
                || MetaDataConstants.MILITARY_EPISODE_SNL.equals(type) || MetaDataConstants.MILITARY_EPISODE_SNNL
                .equals(type));
    }

}