/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache license, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the license for the specific language governing permissions and
 * limitations under the license.
 */

package org.apache.commons.text.lookup;

import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang3.ClassUtils;

/**
 * <p>
 * A specialized lookup implementation that allows access to constant fields of classes.
 * </p>
 * <p>
 * Sometimes it is necessary in a configuration file to refer to a constant defined in a class. This can be done with
 * this lookup implementation. Variable names passed in must be of the form {@code apackage.AClass.AFIELD}. The
 * {@code lookup(String)} method will split the passed in string at the last dot, separating the fully qualified class
 * name and the name of the constant (i.e. <b>static final</b>) member field. Then the class is loaded and the field's
 * value is obtained using reflection.
 * </p>
 * <p>
 * Once retrieved values are cached for fast access. This class is thread-safe. It can be used as a standard (i.e.
 * global) lookup object and serve multiple clients concurrently.
 * </p>
 * <p>
 * This class was adapted from Apache Commons Configuration.
 * </p>
 *
 * @since 1.5
 */
class ConstantStringLookup extends AbstractStringLookup {

    /** Constant for the field separator. */
    private static final char FIELD_SEPRATOR = '.';

    /**
     * Defines the singleton for this class.
     */
    static final ConstantStringLookup INSTANCE = new ConstantStringLookup();

    /** An internally used cache for already retrieved values. */
    private static ConcurrentHashMap<String, String> constantCache = new ConcurrentHashMap<>();

    /**
     * Clears the shared cache with the so far resolved constants.
     */
    static void clear() {
        constantCache.clear();
    }

    /**
     * Tries to resolve the specified variable. The passed in variable name is interpreted as the name of a <b>static
     * final</b> member field of a class. If the value has already been obtained, it can be retrieved from an internal
     * cache. Otherwise this method will invoke the {@code resolveField()} method and pass in the name of the class and
     * the field.
     *
     * @param key
     *            the name of the variable to be resolved
     * @return the value of this variable or <b>null</b> if it cannot be resolved
     */
    @Override
    public synchronized String lookup(final String key) {
        if (key == null) {
            return null;
        }
        String result;
        result = constantCache.get(key);
        if (result != null) {
            return result;
        }
        final int fieldPos = key.lastIndexOf(FIELD_SEPRATOR);
        if (fieldPos < 0) {
            return null;
        }
        try {
            final Object value = resolveField(key.substring(0, fieldPos), key.substring(fieldPos + 1));
            if (value != null) {
                final String string = Objects.toString(value, null);
                constantCache.put(key, string);
                result = string;
            }
        } catch (final Exception ex) {
            // TODO it would be nice to log
            return null;
        }
        return result;
    }

    /**
     * Determines the value of the specified constant member field of a class. This implementation will call
     * {@code fetchClass()} to obtain the {@code java.lang.Class} object for the target class. Then it will use
     * reflection to obtain the field's value. For this to work the field must be accessable.
     *
     * @param className
     *            the name of the class
     * @param fieldName
     *            the name of the member field of that class to read
     * @return the field's value
     * @throws Exception
     *             if an error occurs
     */
    protected Object resolveField(final String className, final String fieldName) throws Exception {
        final Class<?> clazz = fetchClass(className);
        if (clazz == null) {
            return null;
        }
        return clazz.getField(fieldName).get(null);
    }

    /**
     * Loads the class with the specified name. If an application has special needs regarding the class loaders to be
     * used, it can hook in here. This implementation delegates to the {@code getClass()} method of Commons Lang's
     * <code><a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/ClassUtils.html">
     * ClassUtils</a></code>.
     *
     * @param className
     *            the name of the class to be loaded
     * @return the corresponding class object
     * @throws ClassNotFoundException
     *             if the class cannot be loaded
     */
    protected Class<?> fetchClass(final String className) throws ClassNotFoundException {
        return ClassUtils.getClass(className);
    }
}
