/********************************************************************
 * Copyright © 2005 VHA. All rights reserved
 ********************************************************************/
package gov.va.med.esr.common.rule.service;

// Java classes
import gov.va.med.esr.common.infra.ImpreciseDateUtils;
import gov.va.med.esr.common.model.financials.FinancialStatement;
import gov.va.med.esr.common.model.financials.SpouseFinancials;
import gov.va.med.esr.common.model.lookup.Relationship;
import gov.va.med.esr.common.model.lookup.SSNType;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.person.SSN;
import gov.va.med.esr.common.model.person.Spouse;
import gov.va.med.esr.common.rule.service.impl.RuleValidationMessage;
import gov.va.med.esr.common.util.RuleAbstractTestCase;
import gov.va.med.fw.validation.ValidationFieldMessage;
import gov.va.med.fw.validation.ValidationMessages;

import java.math.BigDecimal;

/**
 * @author Muddaiah Ranga
 * @version 1.0
 */

public class SpouseValidationTest extends  RuleAbstractTestCase  
{
	public SpouseValidationTest(String testName)throws Exception 
	{
		super(testName);
	}
	
	/**
	 * Has no spouse data.
	 */
	public void testHasNoSpouseData() throws Exception 
    {

        
        Person incoming = this.buildPerson();
        Person onFile = (Person)incoming.clone();
        Person pristine = (Person)onFile.clone();
        
        Integer incomeYear = new Integer(2004);
        //VAFacility sourceFacility = this.getLookupService().getVaFacilityByCode(VAFacility.CODE_HEC.getName());
         
        SpouseFinancials spouseFinancials = createSpouseFinancials(null);
        FinancialStatement stmt = createFinancialStatement();
        stmt.addSpouseFinancials(spouseFinancials);
        
        incoming.setFinancialStatement(incomeYear,stmt);
        try
        {
            ValidationMessages messages = this.getRuleValidationService().validateSpouseFinancials(incomeYear,spouseFinancials,incoming,onFile,true,true);
			
            //No Validation errors should be found
			assertTrue(messages.isEmpty());
        }
        catch( Exception e )
        {
            logger.debug( "Got an un-expected validation exception ", e );
            this.fail( "Got an un-expected validation exception", e );
        }
        
    }
	
	/**
	 * Tests that the spouse SSN is not same as veteran's SSN.
	 */
    public void testSameSSNAsVeteran() throws Exception 
    {
        Person incoming = this.buildPerson();
        
        Person onFile = (Person)incoming.clone();
        Person pristine = (Person)onFile.clone();
        
        
        SSN ssn = incoming.getOfficialSsn();
        if(ssn == null)
        {
            ssn = createSSN("123-12-1234");
            SSNType officalType = (SSNType)this.getLookupService().getByCode(SSNType.class,SSNType.CODE_ACTIVE.getName());
            ssn.setType(officalType);
            incoming.addSsn(ssn);
        }
        else
        {
            ssn.setSsnText("123-12-1234");    
        }
        
        Integer incomeYear = new Integer(2004);
        //VAFacility sourceFacility = this.getLookupService().getVaFacilityByCode(VAFacility.CODE_HEC.getName());
         
        Spouse spouse = new Spouse();
        spouse.setName(createName());
        
        SSN spouseSSN = (SSN)ssn.clone();
        
        spouse.addSsn(spouseSSN);
        spouse.setRelationship(getLookupService().getRelationshipByCode(Relationship.CODE_SPOUSE.getName()));
        
        SpouseFinancials spouseFinancials = createSpouseFinancials(spouse);

        
        FinancialStatement stmt = createFinancialStatement();
        stmt.addSpouseFinancials(spouseFinancials);
        
        incoming.setFinancialStatement(incomeYear,stmt);
        
        try
        {
            ValidationMessages messages = this.getRuleValidationService().validateSpouseFinancials(incomeYear,spouseFinancials,incoming,onFile,true,true);
            assertNotNull(messages);

			assertTrue(!messages.isEmpty());
			assertTrue((messages.getCount() == 1));
			
			ValidationFieldMessage firstMessage = (ValidationFieldMessage)messages.get().next(); 
			
			assertEquals(firstMessage.getKey(),RuleValidationMessage.INVALID_SPOUSE_SSN_SAME_AS_VETERAN.getName() );
        }
        catch( Exception e )
        {
            logger.debug( "Got an un-expected validation exception ", e );
            this.fail( "Got an un-expected validation exception", e );
        }
        
    }
    
    /**
     * Tests that the DOB is after marriage date.
     */
	public void testDOBAfterMarriageDate() throws Exception
	{
        Person incoming = this.buildPerson();
        
        Person onFile = (Person)incoming.clone();
        Person pristine = (Person)onFile.clone();
        Integer incomeYear = new Integer(2004);
        //VAFacility sourceFacility = this.getLookupService().getVaFacilityByCode(VAFacility.CODE_HEC.getName());
         
        Spouse spouse = new Spouse();
        spouse.setName(createName());
        spouse.setDob(ImpreciseDateUtils.createImpreciseDate(1974,1,1));
        spouse.setMarriageDate(ImpreciseDateUtils.createImpreciseDate(1970,1,1));
        
        SpouseFinancials spouseFinancials = createSpouseFinancials(spouse);

        
        FinancialStatement stmt = createFinancialStatement();
        stmt.addSpouseFinancials(spouseFinancials);
        
        incoming.setFinancialStatement(incomeYear,stmt);
        
        try 
        {
            ValidationMessages messages = this.getRuleValidationService().validateSpouseFinancials(incomeYear,spouseFinancials,incoming,onFile,true,true);
            assertNotNull(messages);
			
			assertTrue(!messages.isEmpty());
			assertTrue((messages.getCount() == 1));
			
			ValidationFieldMessage firstMessage = (ValidationFieldMessage)messages.get().next(); 
			
			assertEquals(firstMessage.getKey(),RuleValidationMessage.INVALID_DOB_AFTER_MARRIAGE_DATE.getName() );
		}
		catch( Exception e )
		{
		    logger.debug( "Got an un-expected validation exception ", e );
			this.fail( "Got an un-expected validation exception", e );
		}
        
	}
	
	/**
	 * Tests that the Marriage date is after spouse inactive date.
	 */
	public void testMarriageDateAfterSpouseInactiveDate() throws Exception
	{
        Person incoming = this.buildPerson();
        
        Person onFile = (Person)incoming.clone();
        Person pristine = (Person)onFile.clone();
        Integer incomeYear = new Integer(2004);
        //VAFacility sourceFacility = this.getLookupService().getVaFacilityByCode(VAFacility.CODE_HEC.getName());
         
        Spouse spouse = new Spouse();
        spouse.setName(createName());
        spouse.setDob(ImpreciseDateUtils.createImpreciseDate(1974,1,1));
        spouse.setMarriageDate(ImpreciseDateUtils.createImpreciseDate(1994,1,1));
        spouse.setEndDate(getDate(1990,1,1));
        
        SpouseFinancials spouseFinancials = createSpouseFinancials(spouse);

        FinancialStatement stmt = createFinancialStatement();
        stmt.addSpouseFinancials(spouseFinancials);
        
        incoming.setFinancialStatement(incomeYear,stmt);
        
        try 
        {
            ValidationMessages messages = this.getRuleValidationService().validateSpouseFinancials(incomeYear,spouseFinancials,incoming,onFile,false,true);
            assertNotNull(messages);
			
			assertTrue(!messages.isEmpty());
			assertTrue((messages.getCount() == 1));
			
			ValidationFieldMessage firstMessage = (ValidationFieldMessage)messages.get().next(); 
			
			assertEquals(firstMessage.getKey(),RuleValidationMessage.INVALID_MARRIAGE_DATE_AFTER_INACTIVE_DATE.getName() );
		}
		catch( Exception e )
		{
		    logger.debug( "Got an un-expected validation exception ", e );
			this.fail( "Got an un-expected validation exception", e );
		}
        
	}
	
    public void testContributedToSpouseNotApplicable() throws Exception {
        Person incoming = this.buildPerson();
        
        Person onFile = (Person)incoming.clone();
        Person pristine = (Person)onFile.clone();
        Integer incomeYear = new Integer(2013);
         
        Spouse spouse = new Spouse();
        spouse.setName(createName());
        spouse.setDob(ImpreciseDateUtils.createImpreciseDate(1974,1,1));
        spouse.setMarriageDate(ImpreciseDateUtils.createImpreciseDate(1994,1,1));
        
        SpouseFinancials spouseFinancials = createSpouseFinancials(spouse);

        spouseFinancials.setLivedWithPatient(Boolean.TRUE);
        
        FinancialStatement stmt = createFinancialStatement();
        stmt.addSpouseFinancials(spouseFinancials);
        stmt.setContributionToSpouse(null);        
        stmt.setContributedToSpouseInd(Boolean.TRUE);
        incoming.setFinancialStatement(incomeYear,stmt);
        assertNotNull(incoming.getFinancialStatement(incomeYear));
        try 
        {
            ValidationMessages messages = this.getRuleValidationService().validateSpouseFinancials(incomeYear,spouseFinancials,incoming,onFile,true,true);
            assertNotNull(messages);
            
            assertTrue(!messages.isEmpty());
            assertTrue((messages.getCount() == 1));
            
            ValidationFieldMessage firstMessage = (ValidationFieldMessage)messages.get().next(); 
            
            assertEquals(firstMessage.getKey(),RuleValidationMessage.CONTRIBUTED_TO_SPOUSE_NOT_APPLICABLE.getName() );
        }
        catch( Exception e )
        {
            logger.debug( "Got an un-expected validation exception ", e );
            this.fail( "Got an un-expected validation exception", e );
        }
        
    }
    
    public void testSpouseContributedAmountNotApplicable() throws Exception {
        Person incoming = this.buildPerson();
        
        Person onFile = (Person)incoming.clone();
        Person pristine = (Person)onFile.clone();
        Integer incomeYear = new Integer(2013);
         
        Spouse spouse = new Spouse();
        spouse.setName(createName());
        spouse.setDob(ImpreciseDateUtils.createImpreciseDate(1974,1,1));
        spouse.setMarriageDate(ImpreciseDateUtils.createImpreciseDate(1994,1,1));
        
        SpouseFinancials spouseFinancials = createSpouseFinancials(spouse);

        spouseFinancials.setLivedWithPatient(Boolean.TRUE);
        
        FinancialStatement stmt = createFinancialStatement();
        stmt.addSpouseFinancials(spouseFinancials);
        stmt.setContributionToSpouse(new BigDecimal(1000));
        stmt.setContributedToSpouseInd(null);
   
        incoming.setFinancialStatement(incomeYear,stmt);
        
        try 
        {
            ValidationMessages messages = this.getRuleValidationService().validateSpouseFinancials(incomeYear,spouseFinancials,incoming,onFile,true,true);
            assertNotNull(messages);
            
            assertTrue(!messages.isEmpty());
            assertTrue((messages.getCount() == 1));
            
            ValidationFieldMessage firstMessage = (ValidationFieldMessage)messages.get().next(); 
            
            assertEquals(firstMessage.getKey(),"SPOUSAL_CONTRIBUTION_NOT_APPLICABLE" );
        }
        catch( Exception e )
        {
            logger.debug( "Got an un-expected validation exception ", e );
            this.fail( "Got an un-expected validation exception", e );
        }
        
    }       
}


