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

import java.util.Date;

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

import gov.va.med.esr.common.infra.ImpreciseDate;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.util.AbstractCommonTestCase;
import gov.va.med.esr.common.builder.entity.BooleanBuilder;
import gov.va.med.esr.messaging.builder.message.DateFormatter;
import gov.va.med.esr.messaging.util.AbstractMessagingTest;
import gov.va.med.esr.service.PersonHelperService;
import gov.va.med.esr.service.UnknownLookupCodeException;
import gov.va.med.esr.service.UnknownLookupTypeException;
import gov.va.med.fw.model.lookup.AbstractLookup;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.util.AbstractTestCase;
import gov.va.med.fw.util.builder.BuilderException;

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

{/*
  * public BaseSegmentsTestDataValidator(String name) { super(name); }
  */
    private BooleanBuilder booleanBuilder;

    /*
     * protected BooleanBuilder getBooleanBuilder() throws ServiceException { if
     * (booleanBuilder == null) { booleanBuilder = (BooleanBuilder) broker
     * .getComponent("booleanBuilder"); }
     * 
     * return booleanBuilder; }
     */
    /**
     * @param element
     * @return
     */
    protected static String getElement(Element element, String tagName)
    {
        String data = null;
        NodeList node = element.getElementsByTagName(tagName);
        if (node != null)
        {
            Element dataElement = (Element) node.item(0);
            if (dataElement != null)
            {
                data = getCharacterDataFromElement(dataElement);
            }
        }
        return data;
    }

    /**
     * @param elementName
     * @return
     */
    protected static String getSubElementData(Element element, String elementName,
            String subElementStr)
    {
        String data = null;
        Element subElement = getSubElement(element, elementName, subElementStr);
        if (subElement != null)
        {
            data = getCharacterDataFromElement(subElement);
        }
        return data;

    }

    protected static Element getSubElement(Element element, String elementName,
            String subElementStr)
    {
        Element firstElement = null;
        if(element == null)
            return null;
        
        NodeList nodes = element.getElementsByTagName(elementName);
        if (nodes != null)
        {
            for (int i = 0; i < nodes.getLength(); i++)
            {
                Element subElement = (Element) nodes.item(i);
                NodeList node = subElement.getElementsByTagName(subElementStr);
                firstElement = (Element) node.item(0);

            }
        }
        return firstElement;
    }

    protected static String getCharacterDataFromElement(Element e)
    {
        String data = null;
        Node child = e.getFirstChild();
        if (child instanceof CharacterData)
        {
            CharacterData cd = (CharacterData) child;
            data = cd.getData();
        }
        return data;
    }

    /**
     * If the expectedResult(data from message) is not null and not empty but
     * BOM is null, fail the test.
     * 
     * If the expectedResult(data from message) is null or empty but BOM is NOT
     * null, fail the test.
     * 
     * @param expectedResult
     * @param bom
     * @param failureMessage
     */
    protected static void validateNotNull(String expectedResult, Object bom,
            String failureMessage)
    {
        if (expectedResult != null && expectedResult.length() > 0
                && bom == null)
        {
            fail(failureMessage);
        }

        /*
         * if (expectedResult == null || expectedResult.length() == 0 && bom !=
         * null) { fail(failureMessage); }
         */
    }

    /**
     * @param incomeTestStatus
     * @param dateFromMsg
     */
    protected static void validateDate(Date date, String dateFromMsg,
            String nullMessage, String doesNotMatchMessage)
    {
        validateNotNull(dateFromMsg, date, nullMessage);
        if (date != null)
        {
            assertEquals(doesNotMatchMessage, dateFromMsg, DateFormatter
                    .formatDate(date));
        }
    }

    /**
     * @param incomeTestStatus
     * @param dateFromMsg
     */
    protected static void validateImpreciseDate(ImpreciseDate date,
            String dateFromMsg, String nullMessage, String doesNotMatchMessage)
    {
        validateNotNull(dateFromMsg, date, nullMessage);
        if (date != null)
        {
            assertEquals(doesNotMatchMessage, dateFromMsg, DateFormatter
                    .formatDate(date));
        }
    }

    protected static String getSendingFacilityStationNumber(Document document)
    {
        NodeList mshNodes = document.getElementsByTagName(MSH);
        Element mshElement = (Element) mshNodes.item(0);
        String sendingFacilityStationNumber = getSubElementData(mshElement,
                MSH_4, HD_1);

        return sendingFacilityStationNumber;
    }

    protected static void assertLookupCode(AbstractLookup lookup,
            String expectedCodeValue, String failureMessage)
    {
        if (expectedCodeValue == null)
        {
            assertNull(failureMessage, lookup);
        } else
        {//if expectedCodeValue != null
            if (lookup == null)
            {
                fail(failureMessage);
            } else
            {
                assertEquals(failureMessage, expectedCodeValue, lookup
                        .getCode());
            }
        }
    }

    protected static void assertLookupDescription(AbstractLookup lookup,
            String expectedCodeValue, String failureMessage)
    {
        if (expectedCodeValue == null)
        {
            assertNull(failureMessage, lookup);
        } else
        {//if expectedCodeValue != null
            if (lookup == null)
            {
                fail(failureMessage);
            } else
            {
                assertEquals(failureMessage, expectedCodeValue.toUpperCase(),
                        lookup.getDescription().toUpperCase());
            }
        }
    }

    public Boolean buildBoolean(String value)
    {
        return ("Y".equalsIgnoreCase(value) || "1".equalsIgnoreCase(value)) ? Boolean.TRUE
                : (("N".equalsIgnoreCase(value) || "0".equalsIgnoreCase(value)) ? Boolean.FALSE
                        : null);
    }

}