/**
 * 
 */


package gov.va.med.cds.audit.persistence.hibernate;


import gov.va.med.cds.audit.AbstractAuditLog;
import gov.va.med.cds.audit.ClientMappingPathways;
import gov.va.med.cds.audit.FilterIdWrapper;
import gov.va.med.cds.audit.TemplateIdWrapper;
import gov.va.med.cds.audit.VhimReadPathwaysResponseAuditLog;
import gov.va.med.cds.audit.persistence.AuditLogPersistenceManagerInterface;

import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.orm.hibernate4.HibernateTemplate;


/**
 * @author DNS   egberb
 *
 */
public class HibernatePathwaysAuditLogPersistenceManager
    implements
        AuditLogPersistenceManagerInterface
{
    private static final Log logger = LogFactory.getLog( HibernatePathwaysAuditLogPersistenceManager.class );
    private HibernateTemplate hibernateTemplate;
    private String appName;


    public String getAppName( )
    {
        return appName;
    }


    @Resource
    public void setAppName( String appName )
    {
        this.appName = appName;
    }


    /* (non-Javadoc)
     * @see gov.va.med.cds.audit.persistence.AuditLogPersistenceManagerInterface#storeAuditLog(gov.va.med.cds.audit.ReadAuditLog)
     */
    @SuppressWarnings( "unchecked" )
    @Override
    public void storeAuditLog( AbstractAuditLog auditLog )
    {
        VhimReadPathwaysResponseAuditLog pathwaysAuditLog = null;

        try
        {
            if ( !( auditLog instanceof VhimReadPathwaysResponseAuditLog ) )
            {
                throw new IllegalArgumentException( String.format( "Unexpected Audit Log Type: %s.", auditLog.getClass().getName() ) );
            }

            pathwaysAuditLog = ( VhimReadPathwaysResponseAuditLog )auditLog;

            persistTemplateIdWrapper( pathwaysAuditLog );
            persistFilterIdWrapper( pathwaysAuditLog );

            // find client mapping
            long tId = pathwaysAuditLog.getTemplateIdWrapper().getId();
            long fId = pathwaysAuditLog.getFilterIdWrapper().getId();
            String clientName = pathwaysAuditLog.getClientId();
            List<ClientMappingPathways> hibernateResult = (List<ClientMappingPathways>)hibernateTemplate.findByNamedQueryAndNamedParam( "pathways.clientmapping.filter.template", new String[] {
                            "templateId", "filterId", "clientName" }, new Object[] { tId, fId, clientName } );
            
            if ( hibernateResult.size() == 1 )
            {
                pathwaysAuditLog.setClientMappingPathways( hibernateResult.get( 0 ) );
                if ( auditLog.getFacility() == null )
                {
                    auditLog.setFacility( pathwaysAuditLog.getClientMappingPathways().getShortName() );
                }
            }
            else
            {
                pathwaysAuditLog.setClientMappingPathways( null );
            }

            hibernateTemplate.save( pathwaysAuditLog );
            hibernateTemplate.flush();
        }
        catch ( Exception ex )
        {
            logger.error( gov.va.med.cds.util.LogMessageUtil.buildMessage( null, null, appName, "Error Auditing READ request message. " ), ex );
        }

    }


    @SuppressWarnings( "unchecked" )
    private void persistTemplateIdWrapper( AbstractAuditLog auditLog )
    {
        List<TemplateIdWrapper> hibernateTemplateIds = ( List<TemplateIdWrapper> )hibernateTemplate.findByNamedQueryAndNamedParam( "template.name",
                        new String[] { "templateName", "templateName" }, new String[] { auditLog.getTemplateIdWrapper().getTemplateId(),
                                        auditLog.getTemplateIdWrapper().getTemplateId() } );

        if ( hibernateTemplateIds.size() < 1 )
        {
            hibernateTemplate.save( auditLog.getTemplateIdWrapper() );
        }
        else
        {
            auditLog.setTemplateIdWrapper( hibernateTemplateIds.get( 0 ) );
        }
    }


    @SuppressWarnings( "unchecked" )
    private void persistFilterIdWrapper( VhimReadPathwaysResponseAuditLog auditLog )
    {
        List<FilterIdWrapper> hibernateFilterIds = ( List<FilterIdWrapper> )hibernateTemplate.findByNamedQueryAndNamedParam( "filter.name",
                        new String[] { "filterName", "filterName" }, new String[] { auditLog.getFilterIdWrapper().getFilterId(),
                                        auditLog.getFilterIdWrapper().getFilterId() } );
        if ( hibernateFilterIds.size() < 1 )
        {
            hibernateTemplate.save( auditLog.getFilterIdWrapper() );
        }
        else
        {
            auditLog.setFilterIdWrapper( hibernateFilterIds.get( 0 ) );
        }
    }


    public void setHibernateTemplate( HibernateTemplate hibernateTemplate )
    {
        this.hibernateTemplate = hibernateTemplate;
    }

}