/*
 * 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.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
{

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

    // Cached stuff
    private String uri;
    private String baseName;
    private String rootUri;
    private String extension;
    private String decodedAbsPath;

    private String key = null;

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

    @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 filename
     * @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 absPath The absolute path.
     * @param type The FileType.
     * @return The FileName.
     */
    public abstract FileName createName(String absPath, FileType type);

    /**
     * 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;
        }
        else 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 filesystem.
     * @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 (uri == null)
        {
            uri = createURI();
        }
        return uri;
    }

    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(useAbsolutePath ? absPath : getPath());
        return buffer.toString();
    }


    /**
     * 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 ".";
        }
        else 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++)
        {
        }

        if (pos == basePathLen && pos == pathLen)
        {
            // Same names
            return ".";
        }
        else 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 filenames 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>
     * Once attached it will be changed to reflect the real type of this resource.
     *
     * @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)
        {
            if (path.length() == baseLen
                || baseLen > 1 && path.charAt(baseLen) != SEPARATOR_CHAR
                || path.indexOf(SEPARATOR_CHAR, baseLen + 1) != -1)
            {
                return false;
            }
        }
        else if (scope == NameScope.DESCENDENT)
        {
            if (path.length() == baseLen
                || baseLen > 1 && path.charAt(baseLen) != SEPARATOR_CHAR)
            {
                return false;
            }
        }
        else if (scope == NameScope.DESCENDENT_OR_SELF)
        {
            if (baseLen > 1
                && path.length() > baseLen
                && path.charAt(baseLen) != SEPARATOR_CHAR)
            {
                return false;
            }
        }
        else if (scope != NameScope.FILE_SYSTEM)
        {
            throw new IllegalArgumentException();
        }

        return true;
    }
}
