/*
 * 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.configuration2.io;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.Arrays;
import java.util.Map;

import org.apache.commons.configuration2.ex.ConfigurationException;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * <p>
 * A utility class providing helper methods related to locating files.
 * </p>
 * <p>
 * The methods of this class are used behind the scenes when retrieving
 * configuration files based on different criteria, e.g. URLs, files, or more
 * complex search strategies. They also implement functionality required by the
 * default {@link FileSystem} implementations. Most methods are intended to be
 * used internally only by other classes in the {@code io} package.
 * </p>
 *
 * @since 2.0
 */
public final class FileLocatorUtils
{
    /**
     * Constant for the default {@code FileSystem}. This file system is used by
     * operations of this class if no specific file system is provided. An
     * instance of {@link DefaultFileSystem} is used.
     */
    public static final FileSystem DEFAULT_FILE_SYSTEM =
            new DefaultFileSystem();

    /**
     * Constant for the default {@code FileLocationStrategy}. This strategy is
     * used by the {@code locate()} method if the passed in {@code FileLocator}
     * does not define its own location strategy. The default location strategy
     * is roughly equivalent to the search algorithm used in version 1.x of
     * <em>Commons Configuration</em> (there it was hard-coded though). It
     * behaves in the following way when passed a {@code FileLocator}:
     * <ul>
     * <li>If the {@code FileLocator} has a defined URL, this URL is used as the
     * file's URL (without any further checks).</li>
     * <li>Otherwise, base path and file name stored in the {@code FileLocator}
     * are passed to the current {@code FileSystem}'s {@code locateFromURL()}
     * method. If this results in a URL, it is returned.</li>
     * <li>Otherwise, if the locator's file name is an absolute path to an
     * existing file, the URL of this file is returned.</li>
     * <li>Otherwise, the concatenation of base path and file name is
     * constructed. If this path points to an existing file, its URL is
     * returned.</li>
     * <li>Otherwise, a sub directory of the current user's home directory as
     * defined by the base path is searched for the referenced file. If the file
     * can be found there, its URL is returned.</li>
     * <li>Otherwise, the base path is ignored, and the file name is searched in
     * the current user's home directory. If the file can be found there, its
     * URL is returned.</li>
     * <li>Otherwise, a resource with the name of the locator's file name is
     * searched in the classpath. If it can be found, its URL is returned.</li>
     * <li>Otherwise, the strategy gives up and returns <b>null</b> indicating
     * that the file cannot be resolved.</li>
     * </ul>
     */
    public static final FileLocationStrategy DEFAULT_LOCATION_STRATEGY =
            initDefaultLocationStrategy();

    /** Constant for the file URL protocol */
    private static final String FILE_SCHEME = "file:";

    /** The logger.*/
    private static final Log LOG = LogFactory.getLog(FileLocatorUtils.class);

    /** Property key for the base path. */
    private static final String PROP_BASE_PATH = "basePath";

    /** Property key for the encoding. */
    private static final String PROP_ENCODING = "encoding";

    /** Property key for the file name. */
    private static final String PROP_FILE_NAME = "fileName";

    /** Property key for the file system. */
    private static final String PROP_FILE_SYSTEM = "fileSystem";

    /** Property key for the location strategy. */
    private static final String PROP_STRATEGY = "locationStrategy";

    /** Property key for the source URL. */
    private static final String PROP_SOURCE_URL = "sourceURL";

    /**
     * Extends a path by another component. The given extension is added to the
     * already existing path adding a separator if necessary.
     *
     * @param path the path to be extended
     * @param ext the extension of the path
     * @return the extended path
     */
    static String appendPath(final String path, final String ext)
    {
        final StringBuilder fName = new StringBuilder();
        fName.append(path);

        // My best friend. Paranoia.
        if (!path.endsWith(File.separator))
        {
            fName.append(File.separator);
        }

        //
        // We have a relative path, and we have
        // two possible forms here. If we have the
        // "./" form then just strip that off first
        // before continuing.
        //
        if (ext.startsWith("." + File.separator))
        {
            fName.append(ext.substring(2));
        }
        else
        {
            fName.append(ext);
        }
        return fName.toString();
    }

    /**
     * Helper method for constructing a file object from a base path and a
     * file name. This method is called if the base path passed to
     * {@code getURL()} does not seem to be a valid URL.
     *
     * @param basePath the base path
     * @param fileName the file name (must not be <b>null</b>)
     * @return the resulting file
     */
    static File constructFile(final String basePath, final String fileName)
    {
        File file;

        final File absolute = new File(fileName);
        if (StringUtils.isEmpty(basePath) || absolute.isAbsolute())
        {
            file = absolute;
        }
        else
        {
            file = new File(appendPath(basePath, fileName));
        }

        return file;
    }

    /**
     * Tries to convert the specified file to a URL. If this causes an
     * exception, result is <b>null</b>.
     *
     * @param file the file to be converted
     * @return the resulting URL or <b>null</b>
     */
    static URL convertFileToURL(final File file)
    {
        return convertURIToURL(file.toURI());
    }

    /**
     * Tries to convert the specified URI to a URL. If this causes an exception,
     * result is <b>null</b>.
     *
     * @param uri the URI to be converted
     * @return the resulting URL or <b>null</b>
     */
    static URL convertURIToURL(final URI uri)
    {
        try
        {
            return uri.toURL();
        }
        catch (final MalformedURLException e)
        {
            return null;
        }
    }

    /**
     * Creates a fully initialized {@code FileLocator} based on the specified
     * URL.
     *
     * @param src the source {@code FileLocator}
     * @param url the URL
     * @return the fully initialized {@code FileLocator}
     */
    private static FileLocator createFullyInitializedLocatorFromURL(final FileLocator src,
            final URL url)
    {
        final FileLocator.FileLocatorBuilder fileLocatorBuilder = fileLocator(src);
        if (src.getSourceURL() == null)
        {
            fileLocatorBuilder.sourceURL(url);
        }
        if (StringUtils.isBlank(src.getFileName()))
        {
            fileLocatorBuilder.fileName(getFileName(url));
        }
        if (StringUtils.isBlank(src.getBasePath()))
        {
            fileLocatorBuilder.basePath(getBasePath(url));
        }
        return fileLocatorBuilder.create();
    }

    /**
     * Tries to convert the specified URL to a file object. If this fails,
     * <b>null</b> is returned.
     *
     * @param url the URL
     * @return the resulting file object
     */
    public static File fileFromURL(final URL url)
    {
        return FileUtils.toFile(url);
    }

    /**
     * Returns an uninitialized {@code FileLocatorBuilder} which can be used
     * for the creation of a {@code FileLocator} object. This method provides
     * a convenient way to create file locators using a fluent API as in the
     * following example:
     * <pre>
     * FileLocator locator = FileLocatorUtils.fileLocator()
     *     .basePath(myBasePath)
     *     .fileName("test.xml")
     *     .create();
     * </pre>
     * @return a builder object for defining a {@code FileLocator}
     */
    public static FileLocator.FileLocatorBuilder fileLocator()
    {
        return fileLocator(null);
    }

    /**
     * Returns a {@code FileLocatorBuilder} which is already initialized with
     * the properties of the passed in {@code FileLocator}. This builder can
     * be used to create a {@code FileLocator} object which shares properties
     * of the original locator (e.g. the {@code FileSystem} or the encoding),
     * but points to a different file. An example use case is as follows:
     * <pre>
     * FileLocator loc1 = ...
     * FileLocator loc2 = FileLocatorUtils.fileLocator(loc1)
     *     .setFileName("anotherTest.xml")
     *     .create();
     * </pre>
     * @param src the source {@code FileLocator} (may be <b>null</b>)
     * @return an initialized builder object for defining a {@code FileLocator}
     */
    public static FileLocator.FileLocatorBuilder fileLocator(final FileLocator src)
    {
        return new FileLocator.FileLocatorBuilder(src);
    }

    /**
     * Creates a new {@code FileLocator} object with the properties defined in
     * the given map. The map must be conform to the structure generated by the
     * {@link #put(FileLocator, Map)} method; unexpected data can cause
     * {@code ClassCastException} exceptions. The map can be <b>null</b>, then
     * an uninitialized {@code FileLocator} is returned.
     *
     * @param map the map
     * @return the new {@code FileLocator}
     * @throws ClassCastException if the map contains invalid data
     */
    public static FileLocator fromMap(final Map<String, ?> map)
    {
        final FileLocator.FileLocatorBuilder builder = fileLocator();
        if (map != null)
        {
            builder.basePath((String) map.get(PROP_BASE_PATH))
                    .encoding((String) map.get(PROP_ENCODING))
                    .fileName((String) map.get(PROP_FILE_NAME))
                    .fileSystem((FileSystem) map.get(PROP_FILE_SYSTEM))
                    .locationStrategy(
                            (FileLocationStrategy) map.get(PROP_STRATEGY))
                    .sourceURL((URL) map.get(PROP_SOURCE_URL));
        }
        return builder.create();
    }

    /**
     * Returns a {@code FileLocator} object based on the passed in one whose
     * location is fully defined. This method ensures that all components of the
     * {@code FileLocator} pointing to the file are set in a consistent way. In
     * detail it behaves as follows:
     * <ul>
     * <li>If the {@code FileLocator} has already all components set which
     * define the file, it is returned unchanged. <em>Note:</em> It is not
     * checked whether all components are really consistent!</li>
     * <li>{@link #locate(FileLocator)} is called to determine a unique URL
     * pointing to the referenced file. If this is successful, a new
     * {@code FileLocator} is created as a copy of the passed in one, but with
     * all components pointing to the file derived from this URL.</li>
     * <li>Otherwise, result is <b>null</b>.</li>
     * </ul>
     *
     * @param locator the {@code FileLocator} to be completed
     * @return a {@code FileLocator} with a fully initialized location if
     *         possible or <b>null</b>
     */
    public static FileLocator fullyInitializedLocator(final FileLocator locator)
    {
        if (isFullyInitialized(locator))
        {
            // already fully initialized
            return locator;
        }

        final URL url = locate(locator);
        return url != null ? createFullyInitializedLocatorFromURL(locator,
                url) : null;
    }

    /**
     * Return the path without the file name, for example http://xyz.net/foo/bar.xml
     * results in http://xyz.net/foo/
     *
     * @param url the URL from which to extract the path
     * @return the path component of the passed in URL
     */
    static String getBasePath(final URL url)
    {
        if (url == null)
        {
            return null;
        }

        String s = url.toString();
        if (s.startsWith(FILE_SCHEME) && !s.startsWith("file://"))
        {
            s = "file://" + s.substring(FILE_SCHEME.length());
        }

        if (s.endsWith("/") || StringUtils.isEmpty(url.getPath()))
        {
            return s;
        }
        return s.substring(0, s.lastIndexOf("/") + 1);
    }

    /**
     * Tries to convert the specified base path and file name into a file object.
     * This method is called e.g. by the save() methods of file based
     * configurations. The parameter strings can be relative files, absolute
     * files and URLs as well. This implementation checks first whether the passed in
     * file name is absolute. If this is the case, it is returned. Otherwise
     * further checks are performed whether the base path and file name can be
     * combined to a valid URL or a valid file name. <em>Note:</em> The test
     * if the passed in file name is absolute is performed using
     * {@code java.io.File.isAbsolute()}. If the file name starts with a
     * slash, this method will return <b>true</b> on Unix, but <b>false</b> on
     * Windows. So to ensure correct behavior for relative file names on all
     * platforms you should never let relative paths start with a slash. E.g.
     * in a configuration definition file do not use something like that:
     * <pre>
     * &lt;properties fileName="/subdir/my.properties"/&gt;
     * </pre>
     * Under Windows this path would be resolved relative to the configuration
     * definition file. Under Unix this would be treated as an absolute path
     * name.
     *
     * @param basePath the base path
     * @param fileName the file name (must not be <b>null</b>)
     * @return the file object (<b>null</b> if no file can be obtained)
     */
    static File getFile(final String basePath, final String fileName)
    {
        // Check if the file name is absolute
        final File f = new File(fileName);
        if (f.isAbsolute())
        {
            return f;
        }

        // Check if URLs are involved
        URL url;
        try
        {
            url = new URL(new URL(basePath), fileName);
        }
        catch (final MalformedURLException mex1)
        {
            try
            {
                url = new URL(fileName);
            }
            catch (final MalformedURLException mex2)
            {
                url = null;
            }
        }

        if (url != null)
        {
            return fileFromURL(url);
        }

        return constructFile(basePath, fileName);
    }

    /**
     * Extract the file name from the specified URL.
     *
     * @param url the URL from which to extract the file name
     * @return the extracted file name
     */
    static String getFileName(final URL url)
    {
        if (url == null)
        {
            return null;
        }

        final String path = url.getPath();

        if (path.endsWith("/") || StringUtils.isEmpty(path))
        {
            return null;
        }
        return path.substring(path.lastIndexOf("/") + 1);
    }

    /**
     * Creates the default location strategy. This method creates a combined
     * location strategy as described in the comment of the
     * {@link #DEFAULT_LOCATION_STRATEGY} member field.
     *
     * @return the default {@code FileLocationStrategy}
     */
    private static FileLocationStrategy initDefaultLocationStrategy()
    {
        final FileLocationStrategy[] subStrategies =
                new FileLocationStrategy[] {
                        new ProvidedURLLocationStrategy(),
                        new FileSystemLocationStrategy(),
                        new AbsoluteNameLocationStrategy(),
                        new BasePathLocationStrategy(),
                        new HomeDirectoryLocationStrategy(true),
                        new HomeDirectoryLocationStrategy(false),
                        new ClasspathLocationStrategy()
                };
        return new CombinedLocationStrategy(Arrays.asList(subStrategies));
    }

    /**
     * Returns a flag whether all components of the given {@code FileLocator}
     * describing the referenced file are defined. In order to reference a file,
     * it is not necessary that all components are filled in (for instance, the
     * URL alone is sufficient). For some use cases however, it might be of
     * interest to have different methods for accessing the referenced file.
     * Also, depending on the filled out properties, there is a subtle
     * difference how the file is accessed: If only the file name is set (and
     * optionally the base path), each time the file is accessed a
     * {@code locate()} operation has to be performed to uniquely identify the
     * file. If however the URL is determined once based on the other components
     * and stored in a fully defined {@code FileLocator}, it can be used
     * directly to identify the file. If the passed in {@code FileLocator} is
     * <b>null</b>, result is <b>false</b>.
     *
     * @param locator the {@code FileLocator} to be checked (may be <b>null</b>)
     * @return a flag whether all components describing the referenced file are
     *         initialized
     */
    public static boolean isFullyInitialized(final FileLocator locator)
    {
        if (locator == null)
        {
            return false;
        }
        return locator.getBasePath() != null && locator.getFileName() != null
                && locator.getSourceURL() != null;
    }

    /**
     * Checks whether the specified {@code FileLocator} contains enough
     * information to locate a file. This is the case if a file name or a URL is
     * defined. If the passed in {@code FileLocator} is <b>null</b>, result is
     * <b>false</b>.
     *
     * @param locator the {@code FileLocator} to check
     * @return a flag whether a file location is defined by this
     *         {@code FileLocator}
     */
    public static boolean isLocationDefined(final FileLocator locator)
    {
        return locator != null
                && (locator.getFileName() != null || locator.getSourceURL() != null);
    }

    /**
     * Locates the provided {@code FileLocator}, returning a URL for accessing
     * the referenced file. This method uses a {@link FileLocationStrategy} to
     * locate the file the passed in {@code FileLocator} points to. If the
     * {@code FileLocator} contains itself a {@code FileLocationStrategy}, it is
     * used. Otherwise, the default {@code FileLocationStrategy} is applied. The
     * strategy is passed the locator and a {@code FileSystem}. The resulting
     * URL is returned. If the {@code FileLocator} is <b>null</b>, result is
     * <b>null</b>.
     *
     * @param locator the {@code FileLocator} to be resolved
     * @return the URL pointing to the referenced file or <b>null</b> if the
     *         {@code FileLocator} could not be resolved
     * @see #DEFAULT_LOCATION_STRATEGY
     */
    public static URL locate(final FileLocator locator)
    {
        if (locator == null)
        {
            return null;
        }

        return obtainLocationStrategy(locator).locate(
                obtainFileSystem(locator), locator);
    }

    /**
     * Tries to find a resource with the given name in the classpath.
     *
     * @param resourceName the name of the resource
     * @return the URL to the found resource or <b>null</b> if the resource
     *         cannot be found
     */
    static URL locateFromClasspath(final String resourceName)
    {
        URL url = null;
        // attempt to load from the context classpath
        final ClassLoader loader = Thread.currentThread().getContextClassLoader();
        if (loader != null)
        {
            url = loader.getResource(resourceName);

            if (url != null)
            {
                LOG.debug("Loading configuration from the context classpath (" + resourceName + ")");
            }
        }

        // attempt to load from the system classpath
        if (url == null)
        {
            url = ClassLoader.getSystemResource(resourceName);

            if (url != null)
            {
                LOG.debug("Loading configuration from the system classpath (" + resourceName + ")");
            }
        }
        return url;
    }

    /**
     * Tries to locate the file referenced by the passed in {@code FileLocator}.
     * If this fails, an exception is thrown. This method works like
     * {@link #locate(FileLocator)}; however, in case of a failed location
     * attempt an exception is thrown.
     *
     * @param locator the {@code FileLocator} to be resolved
     * @return the URL pointing to the referenced file
     * @throws ConfigurationException if the file cannot be resolved
     */
    public static URL locateOrThrow(final FileLocator locator)
            throws ConfigurationException
    {
        final URL url = locate(locator);
        if (url == null)
        {
            throw new ConfigurationException("Could not locate: " + locator);
        }
        return url;
    }

    /**
     * Obtains a non-<b>null</b> {@code FileSystem} object from the passed in
     * {@code FileLocator}. If the passed in {@code FileLocator} has a
     * {@code FileSystem} object, it is returned. Otherwise, result is the
     * default {@code FileSystem}.
     *
     * @param locator the {@code FileLocator} (may be <b>null</b>)
     * @return the {@code FileSystem} to be used for this {@code FileLocator}
     */
    static FileSystem obtainFileSystem(final FileLocator locator)
    {
        return locator != null ? ObjectUtils.defaultIfNull(
                locator.getFileSystem(), DEFAULT_FILE_SYSTEM)
                : DEFAULT_FILE_SYSTEM;
    }

    /**
     * Obtains a non <b>null</b> {@code FileLocationStrategy} object from the
     * passed in {@code FileLocator}. If the {@code FileLocator} is not
     * <b>null</b> and has a {@code FileLocationStrategy} defined, this strategy
     * is returned. Otherwise, result is the default
     * {@code FileLocationStrategy}.
     *
     * @param locator the {@code FileLocator}
     * @return the {@code FileLocationStrategy} for this {@code FileLocator}
     */
    static FileLocationStrategy obtainLocationStrategy(final FileLocator locator)
    {
        return locator != null ? ObjectUtils.defaultIfNull(
                locator.getLocationStrategy(), DEFAULT_LOCATION_STRATEGY)
                : DEFAULT_LOCATION_STRATEGY;
    }

    /**
     * Stores the specified {@code FileLocator} in the given map. With the
     * {@link #fromMap(Map)} method a new {@code FileLocator} with the same
     * properties as the original one can be created.
     *
     * @param locator the {@code FileLocator} to be stored
     * @param map the map in which to store the {@code FileLocator} (must not be
     *        <b>null</b>)
     * @throws IllegalArgumentException if the map is <b>null</b>
     */
    public static void put(final FileLocator locator, final Map<String, Object> map)
    {
        if (map == null)
        {
            throw new IllegalArgumentException("Map must not be null!");
        }

        if (locator != null)
        {
            map.put(PROP_BASE_PATH, locator.getBasePath());
            map.put(PROP_ENCODING, locator.getEncoding());
            map.put(PROP_FILE_NAME, locator.getFileName());
            map.put(PROP_FILE_SYSTEM, locator.getFileSystem());
            map.put(PROP_SOURCE_URL, locator.getSourceURL());
            map.put(PROP_STRATEGY, locator.getLocationStrategy());
        }
    }

    /**
     * Convert the specified file into an URL. This method is equivalent
     * to file.toURI().toURL(). It was used to work around a bug in the JDK
     * preventing the transformation of a file into an URL if the file name
     * contains a '#' character. See the issue CONFIGURATION-300 for
     * more details. Now that we switched to JDK 1.4 we can directly use
     * file.toURI().toURL().
     *
     * @param file the file to be converted into an URL
     * @return a URL
     * @throws  MalformedURLException
     *          If the file protocol handler is not found (should not happen)
     *          or if an error occurred while constructing the URL
     */
    static URL toURL(final File file) throws MalformedURLException
    {
        return file.toURI().toURL();
    }

    /**
     * Private constructor so that no instances can be created.
     */
    private FileLocatorUtils()
    {
    }
}
