/*
 * 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.catalina.webresources;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import org.apache.catalina.LifecycleException;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.compat.JrePlatform;
import org.apache.tomcat.util.http.RequestUtil;

public abstract class AbstractFileResourceSet extends AbstractResourceSet {

    private static final Log log = LogFactory.getLog(AbstractFileResourceSet.class);

    protected static final String[] EMPTY_STRING_ARRAY = new String[0];

    private File fileBase;
    private String absoluteBase;
    private String canonicalBase;
    private boolean readOnly = false;
    private Boolean allowLinking;

    protected AbstractFileResourceSet(String internalPath) {
        setInternalPath(internalPath);
    }

    protected final File getFileBase() {
        return fileBase;
    }

    @Override
    public void setReadOnly(boolean readOnly) {
        this.readOnly = readOnly;
    }

    @Override
    public boolean isReadOnly() {
        return readOnly;
    }

    @Override
    public void setAllowLinking(boolean allowLinking) {
        this.allowLinking = Boolean.valueOf(allowLinking);
    }

    @Override
    public boolean getAllowLinking() {
        if (allowLinking == null) {
            return getRoot().getAllowLinking();
        }
        return allowLinking.booleanValue();
    }

    protected final File file(String name, boolean mustExist) {

        if (name.equals("/")) {
            name = "";
        }
        File file = new File(fileBase, name);

        // If the requested names ends in '/', the Java File API will return a
        // matching file if one exists. This isn't what we want as it is not
        // consistent with the Servlet spec rules for request mapping.
        if (name.endsWith("/") && file.isFile()) {
            return null;
        }

        // If the file/dir must exist but the identified file/dir can't be read
        // then signal that the resource was not found
        if (mustExist && !file.canRead()) {
            return null;
        }

        // If allow linking is enabled, files are not limited to being located
        // under the fileBase so all further checks are disabled.
        if (getAllowLinking()) {
            return file;
        }

        // Additional Windows specific checks to handle known problems with
        // File.getCanonicalPath()
        if (JrePlatform.IS_WINDOWS && isInvalidWindowsFilename(name)) {
            return null;
        }

        // Check that this file is located under the WebResourceSet's base
        String canPath = null;
        try {
            canPath = file.getCanonicalPath();
        } catch (IOException ignore) {
            // Ignore
        }
        if (canPath == null || !canPath.startsWith(canonicalBase)) {
            return null;
        }

        /*
         * Ensure that the file is not outside the fileBase. This should not be possible for standard requests (the
         * request is normalized early in the request processing) but might be possible for some access via the Servlet
         * API (e.g. RequestDispatcher) therefore these checks are retained as an additional safety measure.
         * absoluteBase has been normalized so absPath needs to be normalized as well.
         */
        String absPath = normalize(file.getAbsolutePath());
        if (absPath == null || absoluteBase.length() > absPath.length()) {
            return null;
        }

        // Remove the fileBase location from the start of the paths since that
        // was not part of the requested path and the remaining check only
        // applies to the request path
        absPath = absPath.substring(absoluteBase.length());
        canPath = canPath.substring(canonicalBase.length());

        // The remaining request path must start with '/' if it has non-zero length
        if (!canPath.isEmpty() && canPath.charAt(0) != File.separatorChar) {
            return null;
        }

        // Case sensitivity check
        // The normalized requested path should be an exact match the equivalent
        // canonical path. If it is not, possible reasons include:
        // - case differences on case-insensitive file systems
        // - Windows removing a trailing ' ' or '.' from the file name
        //
        // In all cases, a mismatch here results in the resource not being
        // found
        //
        // absPath is normalized so canPath needs to be normalized as well
        // Can't normalize canPath earlier as canonicalBase is not normalized
        if (!canPath.isEmpty()) {
            canPath = normalize(canPath);
        }
        if (!canPath.equals(absPath)) {
            if (!canPath.equalsIgnoreCase(absPath)) {
                // Typically means symlinks are in use but being ignored. Given
                // the symlink was likely created for a reason, log a warning
                // that it was ignored.
                logIgnoredSymlink(getRoot().getContext().getName(), absPath, canPath);
            }
            return null;
        }

        return file;
    }


    protected void logIgnoredSymlink(String contextPath, String absPath, String canPath) {
        // Log issues with configuration files at a higher level
        if (absPath.startsWith("/META-INF/") || absPath.startsWith("/WEB-INF/")) {
            log.error(sm.getString("abstractFileResourceSet.canonicalfileCheckFailed", contextPath, absPath, canPath));
        } else {
            log.warn(sm.getString("abstractFileResourceSet.canonicalfileCheckFailed", contextPath, absPath, canPath));
        }
    }

    private boolean isInvalidWindowsFilename(String name) {
        final int len = name.length();
        if (len == 0) {
            return false;
        }
        // This consistently ~10 times faster than the equivalent regular
        // expression irrespective of input length.
        for (int i = 0; i < len; i++) {
            char c = name.charAt(i);
            if (c == '\"' || c == '<' || c == '>' || c == ':') {
                // These characters are disallowed in Windows file names and
                // there are known problems for file names with these characters
                // when using File#getCanonicalPath().
                // Note: There are additional characters that are disallowed in
                // Windows file names but these are not known to cause
                // problems when using File#getCanonicalPath().
                return true;
            }
        }
        // Windows does not allow file names to end in ' ' unless specific low
        // level APIs are used to create the files that bypass various checks.
        // File names that end in ' ' are known to cause problems when using
        // File#getCanonicalPath().
        return name.charAt(len - 1) == ' ';
    }


    /**
     * Return a context-relative path, beginning with a "/", that represents the canonical version of the specified path
     * after ".." and "." elements are resolved out. If the specified path attempts to go outside the boundaries of the
     * current context (i.e. too many ".." path elements are present), return <code>null</code> instead.
     *
     * @param path Path to be normalized
     */
    private String normalize(String path) {
        return RequestUtil.normalize(path, File.separatorChar == '\\');
    }

    @Override
    public URL getBaseUrl() {
        try {
            return getFileBase().toURI().toURL();
        } catch (MalformedURLException e) {
            return null;
        }
    }

    /**
     * {@inheritDoc}
     * <p>
     * This is a NO-OP by default for File based resource sets.
     */
    @Override
    public void gc() {
        // NO-OP
    }


    // -------------------------------------------------------- Lifecycle methods

    @Override
    protected void initInternal() throws LifecycleException {
        fileBase = new File(getBase(), getInternalPath());
        checkType(fileBase);

        this.absoluteBase = normalize(fileBase.getAbsolutePath());

        try {
            this.canonicalBase = fileBase.getCanonicalPath();
        } catch (IOException ioe) {
            throw new IllegalArgumentException(ioe);
        }

        // Need to handle mapping of the file system root as a special case
        if ("/".equals(this.absoluteBase)) {
            this.absoluteBase = "";
        }
        if ("/".equals(this.canonicalBase)) {
            this.canonicalBase = "";
        }
    }


    protected abstract void checkType(File file);
}