package gov.va.vinci.dart.log4j2;

import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.selector.ClassLoaderContextSelector;

import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

/**
 * @author
 * @since 7/22/13
 */
public class CocoonModeContextSelector extends ClassLoaderContextSelector {
    // Cocoon looks for this system property to determine its running mode.
    // Let log4j do the same.
    private static final String COCOON_SYSTEM_PROPERTY = "org.apache.cocoon.mode";

    // The Cocoon default running property is "prod" so definitely override it!
    private static final String DEFAULT_RUNNING_MODE = "dev";

    // Default location of the mode-specific properties files
    private static final String PROPERTIES_PATH_TEMPLATE = "/META-INF/cocoon/log4j/%1$s/log4j2_%1$s.xml";

    /**
     * Reads the <code>org.apache.cocoon.mode</code> system property to determine which log4j
     * configuration file to load. The following restrictions apply to the property file(s):
     * <p>
     * <ul>
     * <li>The file(s) must be located in <code>/WEB-INF/classes/META-INF/log4j/[mode]</code>
     * <li>The format of the file name is: <code>log4j2_[mode].xml</code>
     * <li>If the <code>org.apache.cocoon.mode</code> system property is not found, then mode defaults to <code>dev</code>.
     * <li>If the configuration file <code>/WEB-INF/classes/META-INF/log4j/[mode]/log4j2_[mode].xml</code>
     * is not found, then the log4j2 defaults are used(@see <a href="http://logging.apache.org/log4j/2.x/manual/configuration.html">Apache Logging Website</a>)
     * </ul>
     * <p>
     * @see ClassLoaderContextSelector
     *
     * @param fqcn
     * @param loader
     * @param currentContext
     * @param configLocation
     * @return
     */
    @Override
    public LoggerContext getContext(String fqcn, ClassLoader loader, boolean currentContext, URI configLocation) {
        if (null == configLocation) {
            // Get the correct properties file for the running mode.
            String mode = getRunningMode();
            String resLoc = String.format(PROPERTIES_PATH_TEMPLATE, mode);
            try {
                URL resUrl = this.getClass().getResource(resLoc);
                if (null != resUrl) {
                    // we found it!
                    configLocation = resUrl.toURI();
                }
            } catch (URISyntaxException e) {
                // This should not happen, but just in case...
                throw new RuntimeException(e);
            }
        }
        return super.getContext(fqcn, loader, currentContext, configLocation);
    }

    public static String getRunningMode() {
        String mode = System.getProperty(COCOON_SYSTEM_PROPERTY);
        if (StringUtils.isBlank(mode)) {
            // No system property so use the default
            mode = DEFAULT_RUNNING_MODE;
        }
        return mode;
    }
}
