/*
 * 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.vfs2.provider;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.vfs2.FileName;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.FileType;
import org.apache.commons.vfs2.NameScope;
import org.apache.commons.vfs2.VFS;

/**
 * A default file name implementation.
 */
public abstract class AbstractFileName implements FileName {

    // URI Characters that are possible in local file names, but must be escaped
    // for proper URI handling.
    //
    // How reserved URI chars were selected:
    //
    // URIs can contain :, /, ?, #, @
    // See https://docs.oracle.com/javase/8/docs/api/java/net/URI.html
    // http://tools.ietf.org/html/rfc3986#section-2.2
    //
    // Since : and / occur before the path, only chars after path are escaped (i.e., # and ?)
    // ? is a reserved filesystem character for Windows and Unix, so can't be part of a file name.
    // Therefore only # is a reserved char in a URI as part of the path that can be in the file name.
    private static final char[] RESERVED_URI_CHARS = { '#', ' ' };

    private final String scheme;
    private final String absPath;
    private FileType type;

    // Cached attributes
    private String uriString;
    private String baseName;
    private String rootUri;
    private String extension;
    private String decodedAbsPath;

    private String key;

    public AbstractFileName(final String scheme, final String absPath, final FileType type) {
        this.rootUri = null;
        this.scheme = scheme;
        this.type = type;
        if (StringUtils.isEmpty(absPath)) {
            this.absPath = ROOT_PATH;
        } else {
            if (absPath.length() > 1 && absPath.endsWith("/")) {
                this.absPath = absPath.substring(0, absPath.length() - 1);
            } else {
                this.absPath = absPath;
            }
        }
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        final AbstractFileName that = (AbstractFileName) o;

        return getKey().equals(that.getKey());
    }

    @Override
    public int hashCode() {
        return getKey().hashCode();
    }

    /**
     * Implement Comparable.
     *
     * @param obj another abstract file name
     * @return negative number if less than, 0 if equal, positive if greater than.
     */
    @Override
    public int compareTo(final FileName obj) {
        final AbstractFileName name = (AbstractFileName) obj;
        return getKey().compareTo(name.getKey());
    }

    /**
     * Returns the URI of the file.
     *
     * @return the FileName as a URI.
     */
    @Override
    public String toString() {
        return getURI();
    }

    /**
     * Factory method for creating name instances.
     *
     * @param absolutePath The absolute path.
     * @param fileType The FileType.
     * @return The FileName.
     */
    public abstract FileName createName(String absolutePath, FileType fileType);

    /**
     * Builds the root URI for this file name. Note that the root URI must not end with a separator character.
     *
     * @param buffer A StringBuilder to use to construct the URI.
     * @param addPassword true if the password should be added, false otherwise.
     */
    protected abstract void appendRootUri(StringBuilder buffer, boolean addPassword);

    /**
     * Returns the base name of the file.
     *
     * @return The base name of the file.
     */
    @Override
    public String getBaseName() {
        if (baseName == null) {
            final int idx = getPath().lastIndexOf(SEPARATOR_CHAR);
            if (idx == -1) {
                baseName = getPath();
            } else {
                baseName = getPath().substring(idx + 1);
            }
        }

        return baseName;
    }

    /**
     * Returns the absolute path of the file, relative to the root of the file system that the file belongs to.
     *
     * @return The path String.
     */
    @Override
    public String getPath() {
        if (VFS.isUriStyle()) {
            return absPath + getUriTrailer();
        }
        return absPath;
    }

    protected String getUriTrailer() {
        return getType().hasChildren() ? "/" : "";
    }

    /**
     * Returns the decoded path.
     *
     * @return The decoded path String.
     * @throws FileSystemException If an error occurs.
     */
    @Override
    public String getPathDecoded() throws FileSystemException {
        if (decodedAbsPath == null) {
            decodedAbsPath = UriParser.decode(getPath());
        }

        return decodedAbsPath;
    }

    /**
     * Returns the name of the parent of the file.
     *
     * @return the FileName of the parent.
     */
    @Override
    public FileName getParent() {
        final String parentPath;
        final int idx = getPath().lastIndexOf(SEPARATOR_CHAR);
        if (idx == -1 || idx == getPath().length() - 1) {
            // No parent
            return null;
        }
        if (idx == 0) {
            // Root is the parent
            parentPath = SEPARATOR;
        } else {
            parentPath = getPath().substring(0, idx);
        }
        return createName(parentPath, FileType.FOLDER);
    }

    /**
     * find the root of the file system.
     *
     * @return The root FileName.
     */
    @Override
    public FileName getRoot() {
        FileName root = this;
        while (root.getParent() != null) {
            root = root.getParent();
        }

        return root;
    }

    /**
     * Returns the URI scheme of this file.
     *
     * @return The protocol used to access the file.
     */
    @Override
    public String getScheme() {
        return scheme;
    }

    /**
     * Returns the absolute URI of the file.
     *
     * @return The absolute URI of the file.
     */
    @Override
    public String getURI() {
        if (uriString == null) {
            uriString = createURI();
        }
        return uriString;
    }

    protected String createURI() {
        return createURI(false, true);
    }

    /**
     * Create a path that does not use the FileType since that field is not immutable.
     *
     * @return The key.
     */
    private String getKey() {
        if (key == null) {
            key = getURI();
        }
        return key;
    }

    /**
     * Returns the URI without a password.
     *
     * @return Returns the URI without a password.
     */
    @Override
    public String getFriendlyURI() {
        return createURI(false, false);
    }

    private String createURI(final boolean useAbsolutePath, final boolean usePassword) {
        final StringBuilder buffer = new StringBuilder();
        appendRootUri(buffer, usePassword);
        buffer.append(handleURISpecialCharacters(useAbsolutePath ? absPath : getPath()));
        return buffer.toString();
    }

    private String handleURISpecialCharacters(String uri) {
        if (!StringUtils.isEmpty(uri)) {
            try {
                // VFS-325: Handle URI special characters in file name
                // Decode the base URI and re-encode with URI special characters
                uri = UriParser.decode(uri);

                return UriParser.encode(uri, RESERVED_URI_CHARS);
            } catch (final FileSystemException e) {
                // Default to base URI value
            }
        }

        return uri;
    }

    /**
     * Converts a file name to a relative name, relative to this file name.
     *
     * @param name The FileName.
     * @return The relative path to the file.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public String getRelativeName(final FileName name) throws FileSystemException {
        final String path = name.getPath();

        // Calculate the common prefix
        final int basePathLen = getPath().length();
        final int pathLen = path.length();

        // Deal with root
        if (basePathLen == 1 && pathLen == 1) {
            return ".";
        }
        if (basePathLen == 1) {
            return path.substring(1);
        }

        final int maxlen = Math.min(basePathLen, pathLen);
        int pos = 0;
        for (; pos < maxlen && getPath().charAt(pos) == path.charAt(pos); pos++) {
            // empty
        }

        if (pos == basePathLen && pos == pathLen) {
            // Same names
            return ".";
        }
        if (pos == basePathLen && pos < pathLen && path.charAt(pos) == SEPARATOR_CHAR) {
            // A descendent of the base path
            return path.substring(pos + 1);
        }

        // Strip the common prefix off the path
        final StringBuilder buffer = new StringBuilder();
        if (pathLen > 1 && (pos < pathLen || getPath().charAt(pos) != SEPARATOR_CHAR)) {
            // Not a direct ancestor, need to back up
            pos = getPath().lastIndexOf(SEPARATOR_CHAR, pos);
            buffer.append(path.substring(pos));
        }

        // Prepend a '../' for each element in the base path past the common
        // prefix
        buffer.insert(0, "..");
        pos = getPath().indexOf(SEPARATOR_CHAR, pos + 1);
        while (pos != -1) {
            buffer.insert(0, "../");
            pos = getPath().indexOf(SEPARATOR_CHAR, pos + 1);
        }

        return buffer.toString();
    }

    /**
     * Returns the root URI of the file system this file belongs to.
     *
     * @return The URI of the root.
     */
    @Override
    public String getRootURI() {
        if (rootUri == null) {
            final StringBuilder buffer = new StringBuilder();
            appendRootUri(buffer, true);
            buffer.append(SEPARATOR_CHAR);
            rootUri = buffer.toString().intern();
        }
        return rootUri;
    }

    /**
     * Returns the depth of this file name, within its file system.
     *
     * @return The depth of the file name.
     */
    @Override
    public int getDepth() {
        final int len = getPath().length();
        if (len == 0 || len == 1 && getPath().charAt(0) == SEPARATOR_CHAR) {
            return 0;
        }
        int depth = 1;
        for (int pos = 0; pos > -1 && pos < len; depth++) {
            pos = getPath().indexOf(SEPARATOR_CHAR, pos + 1);
        }
        return depth;
    }

    /**
     * Returns the extension of this file name.
     *
     * @return The file extension.
     */
    @Override
    public String getExtension() {
        if (extension == null) {
            getBaseName();
            final int pos = baseName.lastIndexOf('.');
            // if ((pos == -1) || (pos == baseName.length() - 1))
            // imario@ops.co.at: Review of patch from adagoubard@chello.nl
            // do not treat file names like
            // .bashrc c:\windows\.java c:\windows\.javaws c:\windows\.jedit c:\windows\.appletviewer
            // as extension
            if (pos < 1 || pos == baseName.length() - 1) {
                // No extension
                extension = "";
            } else {
                extension = baseName.substring(pos + 1).intern();
            }
        }
        return extension;
    }

    /**
     * Determines if another file name is an ancestor of this file name.
     *
     * @param ancestor The FileName to check.
     * @return true if the FileName is an ancestor, false otherwise.
     */
    @Override
    public boolean isAncestor(final FileName ancestor) {
        if (!ancestor.getRootURI().equals(getRootURI())) {
            return false;
        }
        return checkName(ancestor.getPath(), getPath(), NameScope.DESCENDENT);
    }

    /**
     * Determines if another file name is a descendent of this file name.
     *
     * @param descendent The FileName to check.
     * @return true if the FileName is a descendent, false otherwise.
     */
    @Override
    public boolean isDescendent(final FileName descendent) {
        return isDescendent(descendent, NameScope.DESCENDENT);
    }

    /**
     * Determines if another file name is a descendent of this file name.
     *
     * @param descendent The FileName to check.
     * @param scope The NameScope.
     * @return true if the FileName is a descendent, false otherwise.
     */
    @Override
    public boolean isDescendent(final FileName descendent, final NameScope scope) {
        if (!descendent.getRootURI().equals(getRootURI())) {
            return false;
        }
        return checkName(getPath(), descendent.getPath(), scope);
    }

    /**
     * Checks if this file name is a name for a regular file by using its type.
     *
     * @return true if this file is a regular file.
     * @throws FileSystemException may be thrown by subclasses.
     * @see #getType()
     * @see FileType#FILE
     */
    @Override
    public boolean isFile() throws FileSystemException {
        // Use equals instead of == to avoid any class loader worries.
        return FileType.FILE.equals(this.getType());
    }

    /**
     * Returns the requested or current type of this name.
     * <p>
     * The "requested" type is the one determined during resolving the name. n this case the name is a
     * {@link FileType#FOLDER} if it ends with an "/" else it will be a {@link FileType#FILE}.
     * </p>
     * <p>
     * Once attached it will be changed to reflect the real type of this resource.
     * </p>
     *
     * @return {@link FileType#FOLDER} or {@link FileType#FILE}
     */
    @Override
    public FileType getType() {
        return type;
    }

    /**
     * Sets the type of this file e.g. when it will be attached.
     *
     * @param type {@link FileType#FOLDER} or {@link FileType#FILE}
     * @throws FileSystemException if an error occurs.
     */
    void setType(final FileType type) throws FileSystemException {
        if (type != FileType.FOLDER && type != FileType.FILE && type != FileType.FILE_OR_FOLDER) {
            throw new FileSystemException("vfs.provider/filename-type.error");
        }

        this.type = type;
    }

    /**
     * Checks whether a path fits in a particular scope of another path.
     *
     * @param basePath An absolute, normalised path.
     * @param path An absolute, normalised path.
     * @param scope The NameScope.
     * @return true if the path fits in the scope, false otherwise.
     */
    public static boolean checkName(final String basePath, final String path, final NameScope scope) {
        if (scope == NameScope.FILE_SYSTEM) {
            // All good
            return true;
        }

        if (!path.startsWith(basePath)) {
            return false;
        }

        int baseLen = basePath.length();
        if (VFS.isUriStyle()) {
            // strip the trailing "/"
            baseLen--;
        }

        if (scope == NameScope.CHILD) {
            return path.length() != baseLen && (baseLen <= 1 || path.charAt(baseLen) == SEPARATOR_CHAR)
                    && path.indexOf(SEPARATOR_CHAR, baseLen + 1) == -1;
        }
        if (scope == NameScope.DESCENDENT) {
            return path.length() != baseLen && (baseLen <= 1 || path.charAt(baseLen) == SEPARATOR_CHAR);
        }
        if (scope == NameScope.DESCENDENT_OR_SELF) {
            return baseLen <= 1 || path.length() <= baseLen || path.charAt(baseLen) == SEPARATOR_CHAR;
        }
        if (scope != NameScope.FILE_SYSTEM) {
            throw new IllegalArgumentException();
        }

        return true;
    }
}
