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

import java.io.StringReader;
import java.util.Iterator;
import java.util.List;
import java.util.HashSet;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.xml.sax.InputSource;

import gov.va.med.esr.common.infra.ImpreciseDate;
import gov.va.med.esr.common.infra.ImpreciseDateUtils;
import gov.va.med.esr.common.model.CommonEntityKeyFactory;
import gov.va.med.esr.common.model.ee.RatedDisability;
import gov.va.med.esr.common.model.ee.VerificationInfo;
import gov.va.med.esr.common.model.lookup.Disability;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.messaging.service.MessageProcessServiceUtil;
import gov.va.med.esr.messaging.util.AbstractMessagingTest;
import gov.va.med.esr.messaging.xml.XmlFormatter;
import gov.va.med.esr.service.PersonService;
import gov.va.med.esr.common.rule.service.MergeRuleService;
import gov.va.med.fw.hl7.BatchMessage;
import gov.va.med.fw.hl7.Message;

/**
 * Validates the incoming ORUZ11 message from VBA
 * 
 * @author Rajiv Patnaik Created on Jul 29, 2005
 * @version 1.0
 * 
 * Copyright © 2005 VHA. All rights reserved
 */
public class Z11ParserTest extends AbstractMessagingTest
{
	private MergeRuleService mergeRuleService = null;
	
    public Z11ParserTest(String name)
    {
        super(name);
    }
    protected RatedDisability createRatedDisability(Disability type,
			Integer percent, ImpreciseDate origEffRatingDt, ImpreciseDate effRatingDt) throws Exception {
		RatedDisability ratedDisability = new RatedDisability();
		ratedDisability.setPercentage(percent);
		ratedDisability.setServiceConnected(Boolean.TRUE);
		ratedDisability.setDisability(type);
		ratedDisability.setOriginalEffectiveRatingDate(origEffRatingDt);
		ratedDisability.setRatingDate(effRatingDt);
		return ratedDisability;
	}   
    
    
    public void testORUZ11fromVBA() throws Exception
    {
        //Create a BatchMessage object
        BatchMessage batchMessage = (BatchMessage) super.createORUZ11Message();

        //Parses the message into segments
        batchMessage.getSegments();

        //Parses the message into different messages each containing its
        // respective segments
        List messages = batchMessage.getMessages();

        
        /* hijack inbound.xml and reconfigure the z11Parser so that target is visible 
         * 
         */
        Z11Parser parser = (Z11Parser) applicationContext
                .getBean("inbound.z11Parser.target");

        //Build a simple Person in memory
        //Person person = buildSimplePerson();
        //this.attachVerifiedEnrollment(person);
        //this.attachServiceConnectionAward(person);
        Person person = this.getPersonService().getPerson(CommonEntityKeyFactory
                .createPersonIdEntityKey("373971922"));        
        Disability d8599 = this.getLookupService().getDisabilityByCode("8599");
   
        PersonService personService = (PersonService) applicationContext.getBean("personService");
        Person incoming = (Person)person.clone();
        System.out.println("onfile data before message build:");
        for (Iterator i = incoming.getServiceConnectionAward().getRatedDisabilities().iterator(); i.hasNext();){
        	RatedDisability rd = (RatedDisability)i.next();
   		 	System.out.println("type="+rd.getDisability().getCode()+ 
   		 			"  result dates="+rd.getRatingDate() + 
   		 			" and "+ rd.getOriginalEffectiveRatingDate() + 
   		 			" %=" + rd.getPercentage());
        }                
        Person result = null;
        //Right now there is only one message in the BatchMessage object
        for (Iterator iter = messages.iterator(); iter.hasNext();)
        {
            Message message = (Message) iter.next();
            //Parse the message and overlay the info on top of the retrieved
            // Person from database
            incoming = parser.build(incoming, message);
            assertNotNull("Person from parser is null", incoming);
            VerificationInfo vi = createVerificationInfoFromORUZ11();
            result = this.getMessagingService().processNonQueryZ11(incoming, vi);
        }
        System.out.println("result data:"); 
        
        if (result != null) {	               
	        System.out.println("count="+result.getServiceConnectionAward().getRatedDisabilities().size());
	        for (Iterator i = result.getServiceConnectionAward().getRatedDisabilities().iterator(); i.hasNext();){
	        	RatedDisability rd = (RatedDisability)i.next();
	   		 	System.out.println("type="+rd.getDisability().getCode()+ 
	   		 			"  result dates="+rd.getRatingDate() + 
	   		 			" and "+ rd.getOriginalEffectiveRatingDate() + 
	   		 			" %=" + rd.getPercentage());
	        }        
        }
       this.setComplete();
    }
    public void testMergeOfORUZ11fromVBA() throws Exception
    {
        //Create a BatchMessage object
        BatchMessage batchMessage = (BatchMessage) super.createORUZ11Message();

        //Parses the message into segments
        batchMessage.getSegments();

        //Parses the message into different messages each containing its
        // respective segments
        List messages = batchMessage.getMessages();

        
        /* hijack inbound.xml and reconfigure the z11Parser so that target is visible 
         * 
         */
        Z11Parser parser = (Z11Parser) applicationContext
                .getBean("inbound.z11Parser.target");

        //Build a simple Person in memory
        //Person person = buildSimplePerson();
        //this.attachVerifiedEnrollment(person);
        //this.attachServiceConnectionAward(person);
        Person person = this.getPersonService().getPerson(CommonEntityKeyFactory
                .createPersonIdEntityKey("373971922"));        
        Disability d8599 = this.getLookupService().getDisabilityByCode("8599");
   
        PersonService personService = (PersonService) applicationContext.getBean("personService");
        Person incoming = (Person)person.clone();
        System.out.println("onfile data before message build:");
        for (Iterator i = incoming.getServiceConnectionAward().getRatedDisabilities().iterator(); i.hasNext();){
        	RatedDisability rd = (RatedDisability)i.next();
   		 	System.out.println("type="+rd.getDisability().getCode()+ 
   		 			"  result dates="+rd.getRatingDate() + 
   		 			" and "+ rd.getOriginalEffectiveRatingDate() + 
   		 			" %=" + rd.getPercentage());
        }                
        Person result = null;
        Set resultSet = new HashSet();
        //Right now there is only one message in the BatchMessage object
        for (Iterator iter = messages.iterator(); iter.hasNext();)
        {
            Message message = (Message) iter.next();
            //Parse the message and overlay the info on top of the retrieved
            // Person from database
            incoming = parser.build(incoming, message);
            resultSet = this.getMergeRuleService().mergeRatedDisabilitiesFromHL7(incoming.getServiceConnectionAward().getRatedDisabilities(),
            		person.getServiceConnectionAward().getRatedDisabilities());
            
        }
        System.out.println("result data:");        
        System.out.println("count="+resultSet.size());
        for (Iterator i = resultSet.iterator(); i.hasNext();){
        	RatedDisability rd = (RatedDisability)i.next();
   		 	System.out.println("type="+rd.getDisability().getCode()+ 
   		 			"  result dates="+rd.getRatingDate() + 
   		 			" and "+ rd.getOriginalEffectiveRatingDate() + 
   		 			" %=" + rd.getPercentage());
        }        

    }
    public void testORFZ11() throws Exception
    {
        //Create a BatchMessage object
        Message message = (Message) super.createORFZ11Message();

        //Parses the message into segments
        message.getSegments();

        Z11Parser parser = (Z11Parser) applicationContext
                .getBean("inbound.z11Parser.target");

        //Build a simple Person in memory
        //Person person = buildSimplePerson();
        //this.attachVerifiedEnrollment(person);
        //this.attachServiceConnectionAward(person);
        Person person = this.getPersonService().getPerson(CommonEntityKeyFactory
                .createPersonIdEntityKey("373971922"));
        gov.va.med.esr.messaging.service.inbound.PersonFinder finder = 
        	(gov.va.med.esr.messaging.service.inbound.PersonFinder)applicationContext.getBean("personFinderFromVBA");
       // Person person = finder.find(message);
        Disability d8599 = this.getLookupService().getDisabilityByCode("8599");
        
        //the parser returns null.
        PersonService personService = (PersonService) applicationContext.getBean("personService");
        //Person temp = personService.save(person);
        //Person incoming = (Person)temp.clone(); 
        Person incoming = (Person)person.clone();
        System.out.println("onfile data before message build:");
        for (Iterator i = incoming.getServiceConnectionAward().getRatedDisabilities().iterator(); i.hasNext();){
        	RatedDisability rd = (RatedDisability)i.next();
   		 	System.out.println("type="+rd.getDisability().getCode()+ 
   		 			"  result dates="+rd.getRatingDate() + 
   		 			" and "+ rd.getOriginalEffectiveRatingDate() + 
   		 			" %=" + rd.getPercentage());
        }               
        Person result = null;
        //Parse the message and overlay the info on top of the retrieved
        // Person from database
        incoming = parser.build(incoming, message);
        assertNotNull("Person from parser is null", incoming);
        VerificationInfo vi = createVerificationInfoFromORFZ11();
        result = this.getMessagingService().processNonQueryZ11(incoming, vi);

        System.out.println("count="+result.getServiceConnectionAward().getRatedDisabilities().size());
        for (Iterator i = result.getServiceConnectionAward().getRatedDisabilities().iterator(); i.hasNext();){
        	RatedDisability rd = (RatedDisability)i.next();
        	System.out.println("type="+rd.getDisability().getCode()+ 
        			"  result dates="+rd.getRatingDate() + 
        			" and "+ rd.getOriginalEffectiveRatingDate() + 
        			" %=" + rd.getPercentage());
        }        
    }
	/**
	 * @return the mergeRuleService
	 */
	public MergeRuleService getMergeRuleService() {
		return mergeRuleService;
	}
	/**
	 * @param mergeRuleService the mergeRuleService to set
	 */
	public void setMergeRuleService(MergeRuleService mergeRuleService) {
		this.mergeRuleService = mergeRuleService;
	}
    
}