/*
 * #%L
 * Alfresco Search Services
 * %%
 * Copyright (C) 2005 - 2020 Alfresco Software Limited
 * %%
 * This file is part of the Alfresco software. 
 * If the software was purchased under a paid Alfresco license, the terms of 
 * the paid license agreement will prevail.  Otherwise, the software is 
 * provided under the following open source license terms:
 * 
 * Alfresco is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Alfresco is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 * #L%
 */

package org.alfresco.solr.config;

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

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.naming.NoInitialContextException;

/**
 * Helps with configuring and setup of Alfresco and Solr.
 *
 * @author Gethin James
 */
public class ConfigUtil {

    protected final static Logger log = LoggerFactory.getLogger(ConfigUtil.class);

    private static final String JNDI_PREFIX = "java:comp/env/";
    private static final String ENV_PREFIX = "SOLR_";

    /**
     * Finds the property based on looking up the value in one of three places (in order of preference):
     * <ol>
     *  <li>JNDI: via java:comp/env/{propertyName/converted/to/slash}</li>
     *  <li>A Java system property or a Java system property prefixed with solr.</li>
     *  <li>OS environment variable</li>
     * </ol>
     *
     * @return A property
     */
    public static String locateProperty(String propertyName, String defaultValue)
    {

        String propertyValue = null;
        String propertyKey = propertyName;
        String jndiKey =  convertPropertyNameToJNDIPath(propertyKey);
        String envVar = convertPropertyNameToEnvironmentParam(propertyKey);

        // Try JNDI
        try {
            Context c = new InitialContext();
            propertyValue = (String) c.lookup(jndiKey);
            log.debug("Using JNDI key: "+jndiKey+": "+propertyValue );
            return propertyValue;
        } catch (NoInitialContextException e) {
            log.debug("JNDI not configured (NoInitialContextEx)");
        } catch (NamingException e) {
            log.debug("No "+jndiKey+" in JNDI");
        } catch( RuntimeException ex ) {
            log.warn("Odd RuntimeException while testing for JNDI: " + ex.getMessage());
        }

        // Now try system property
        propertyValue = System.getProperty(propertyKey);
        if( propertyValue != null ) {
            log.debug("Using system property "+propertyKey+": " + propertyValue );
            return propertyValue;
        }

        //try system property again with a solr. prefix
        propertyValue = System.getProperty("solr."+propertyKey);
        if( propertyValue != null ) {
            log.debug("Using system property "+"solr."+propertyKey+": " + propertyValue );
            return propertyValue;
        }

        // Now try an environment variable
        propertyValue = System.getenv(envVar);
        if( propertyValue != null ) {
            log.debug("Using environment variable "+envVar+": " + propertyValue );
            return propertyValue;
        }

        //if all else fails then return the default
        log.debug("Using default value for variable "+propertyName+": " + defaultValue );
        return defaultValue;
    }

    /**
     * Takes a property name and splits it via / instead of .
     * @param propertyName
     * @return the property name as a jndi path
     */
    protected static String convertPropertyNameToJNDIPath(String propertyName)
    {
        if (propertyName == null) propertyName = "";
        return JNDI_PREFIX+propertyName.replace('.','/');
    }

    protected static String convertPropertyNameToEnvironmentParam(String propertyName)
    {
        if (propertyName == null) propertyName = "";
        return ENV_PREFIX+propertyName.replace('.','_').toUpperCase();
    }
}
