package gov.va.med.srcalc.vista.vistalink;

import javax.naming.InitialContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Optional;

import gov.va.med.srcalc.ConfigurationException;
import gov.va.med.vistalink.adapter.spi.ConfigurationReader;
import gov.va.med.vistalink.institution.*;

/**
 * Provides VistALink utility methods. These are not srcalc-specific: VistALink could have
 * provided them itself.
 */
public class VistaLinkUtil
{
    private static final Logger LOGGER = LoggerFactory.getLogger(VistaLinkUtil.class);
    
    private static final IPrimaryStationRules STATION_RULES;
    
    // Eagerly get IPrimaryStationRules implementation to find configuration issues early.
    static
    {
        try
        {
            STATION_RULES = PrimaryStationRulesFactory.getPrimaryStationRulesImplementation();
        }
        catch (final ReflectiveOperationException e)
        {
            // getPrimaryStationRulesImplementation() does not document its exceptions,
            // so at least be as specific as we can.
            throw new ConfigurationException(
                    "Could not get configured IPrimaryStationRules implementation.", e);
        }
    }
    
    private VistaLinkUtil()
    {
        // No construction.
    }
    
    private static String getStationFromDivision(final String division)
        throws InstitutionMappingBadStationNumberException
    {
        return STATION_RULES.getPrimaryStationLookupString(division);
    }
    
    private static void tryForceLoad(final String division)
    {
        try
        {
            final String station = getStationFromDivision(division);
            final String configuredJndiName =
                    ConfigurationReader.getJndiNameForStationNumber(station);
            LOGGER.trace(
                    "Got JNDI name {} for division {} from configuration",
                    configuredJndiName, division);
            if (configuredJndiName != null)
            {
                final InitialContext ic = new InitialContext();
                ic.lookup(configuredJndiName);
            }
        }
        catch (final Exception ex)
        {
            LOGGER.info(
                    "Swallowing Exception while trying to force-load division {}",
                    division,
                    ex);
        }
    }
    
    /**
     * Returns the JNDI name of the VistALink ConnectionFactory for the given division,
     * if known.
     */
    public static Optional<String> getJndiNameForDivision(final String division)
    {
        try
        {
            return Optional.of(
                    InstitutionMappingDelegate.getJndiConnectorNameForInstitution(division));
        }
        catch (InstitutionMapNotInitializedException |
                InstitutionMappingNotFoundException ex)
        {
            /*
             * This isn't pretty: VistALink relies on the connectors being eagerly-loaded
             * like WebLogic does, but it isn't standard across application servers. The
             * VistALink code contains the below hack to force initialization but for some
             * reason only enables it on Websphere.
             */
            tryForceLoad(division);

            try
            {
                return Optional.of(
                        InstitutionMappingDelegate.getJndiConnectorNameForInstitution(division));
            }
            catch (InstitutionMapNotInitializedException |
                    InstitutionMappingNotFoundException e)
            {
                LOGGER.debug("Unknown division {}", division, e);
                return Optional.absent();
            }
        }
    }

    /**
     * Returns true if the given division is known to VistALink, false otherwise.
     */
    public static boolean isDivisionKnown(final String division)
    {
        return getJndiNameForDivision(division).isPresent();
    }
    
}

@@ -1314,200 +1314,199 @@
     
-private static String getStationFromDivision(final String division)%0A        throws InstitutionMappingBadStationNumberException%0A    %7B%0A        return STATION_RULES.getPrimaryStationLookup
+/**%0A     * Tries to load the VistALink ConnectionFactory for the given division by explicitly%0A     * reading the configuration file.%0A     */%0A    private static void tryForceLoad(final 
 String
-(
+ 
 divi
@@ -1514,86 +1514,171 @@
 ion)
-;
 %0A    
-%7D
+%7B
 %0A    
-%0A    private static void tryForceLoad(final String division)%0A    %7B
+    // The below technique is tighter coupling with VistALink than I would like, but%0A        // I couldn't find a better way. - David Tombs, 31-Aug-2015
 %0A   
@@ -1735,30 +1735,51 @@
 n = 
-getStationFromDivision
+STATION_RULES.getPrimaryStationLookupString
 (div
@@ -3184,124 +3184,98 @@
   * 
-VistALink code contains the below hack to force initializ
+below hack supports other applic
 ation 
-but for some%0A             * reason only enables it on
+servers (e.g., GlassFish and probably%0A             *
  Web
@@ -3280,16 +3280,17 @@
 ebsphere
+)
 .%0A      

improve some documentation