/********************************************************************
 * Copyright © 2004 VHA. All rights reserved
 ********************************************************************/
package gov.va.med.esr.service.impl;

// Java classes
import java.util.Set;

// Library classes
import org.apache.commons.lang.Validate;

// Framework classes
import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.validation.ValidationMessages;

// ESR classes
import gov.va.med.esr.UseCaseName;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.person.id.PersonEntityKey;
import gov.va.med.esr.service.InsuranceService;

/**
 * Provides methods to process use cases related to a veteran's insurance information either coming from a site or from a UI screen </br> </br> <b>Project: Common</b> </br>
 *
 * @author DNS   LEV
 * @version 1.0
 */
public class InsuranceServiceImpl extends AbstractRuleAwareServiceImpl implements InsuranceService
{

    /**
     * An instance of serialVersionUID
     */
    private static final long serialVersionUID = 1165939113034552584L;
    

    /**
     * A default constructor
     */
    public InsuranceServiceImpl()
    {
        super();
    }

    /** This method implements the following use case: </br>
     * </br>
     * <b>[2218UC22.1]</b> The purpose of this use case is to allow the actor to access  insurance </br>
     * information as well as enter/edit specific veteran insurance information </b></br>
     * </br>
     * <b>[UC22.4]</b> Update Insurance Information </br>
     * </br>
     * <b>[UC22.6]</b> Send Update Message (Z04) </br>
     * </br>
     * <b>Note:</b> This method is mainly called by a UI to update a veteran's insurance information
     * @see gov.va.med.esr.service.InsuranceService#updateInsurance(gov.va.med.esr.common.model.person.Person)
     */
    public ValidationMessages updateInsurance(Person incoming) throws ServiceException 
    {
        Validate.notNull(incoming, "A veteran must not be null");

        // This call should always return a person since a person must have
        // already been querried through a search to display insurance info
        // on a screen
        Person result = this.getPersonService().getPerson((PersonEntityKey)incoming.getEntityKey());

        // Ensure that something changed on the incoming entity as compared to the onFile entity
        ensureEntityChanged(incoming, result);
        
        // Validate that an enrollment record exists for the on-file Person
        validateEnrollmentDetermination(result);

        // Get a collection of insurance policy to pass down to a rule service
        Set policies = incoming.getInsurances();

        VAFacility hec = this.getLookupService().getVaFacilityByCode(VAFacility.CODE_HEC.getCode());

        // Step 1: Update a veteran on file with insurance information then send a Z04 message
        // for updated policy record. If there are any ValidationMessages, return them to the
        //caller after updating the person.
        ValidationMessages messages = this.getInsuranceRuleService().manageInsurancePolicies(policies, result, hec);
        // CCR 12062 prepare data for after advice
        messages = prepareForAfterAdvice(incoming, messages);

        // Save the updated person
        this.getPersonService().save(result);
        
        return messages;
    }
    private ValidationMessages prepareForAfterAdvice(Person incoming, ValidationMessages messages) {
    	// CCR 12062
    	if (messages == null) {
    		// need non-null for new advice to work. Null means there were NO errors in
    		// Insurance processing.
    		messages = new ValidationMessages();
    	}
    	// Indicate that something changed
    	incoming.setChangeEvent(UseCaseName.INSURANCE, "INSURANCE");    		
    	return messages;
    }
    
}