
/* ====================================================================
   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.poi.poifs.filesystem;

import java.io.File;
import java.util.Arrays;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Stream;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 * Class POIFSDocumentPath
 */

public class POIFSDocumentPath {

    private static final Logger LOGGER = LogManager.getLogger(POIFSDocumentPath.class);

    private final String[] components;
    private int hashcode; //lazy-compute hashCode

    /**
     * simple constructor for the path of a document that is in the root of the POIFSFileSystem.
     * The constructor that takes an array of Strings can also be used to create such a
     * POIFSDocumentPath by passing it a null or empty String array
     */
    public POIFSDocumentPath() {
        components = new String[0];
    }

    /**
     * constructor for the path of a document that is not in the root of the POIFSFileSystem
     *
     * @param components the Strings making up the path to a document.
     *      The Strings must be ordered as they appear in the directory hierarchy of the the document.
     *      The first string must be the name of a directory in the root of the POIFSFileSystem, and
     *      every Nth (for N > 1) string thereafter must be the name of a directory in the directory
     *      identified by the (N-1)th string. <p> If the components parameter is null or has zero length,
     *      the POIFSDocumentPath is appropriate for a document that is in the root of a POIFSFileSystem
     *
     * @exception IllegalArgumentException
     *      if any of the elements in the components parameter are null or have zero length
     */
    public POIFSDocumentPath(final String [] components) throws IllegalArgumentException {
        this(null, components);
    }

    /**
     * constructor that adds additional subdirectories to an existing path
     *
     * @param path the existing path
     * @param components the additional subdirectory names to be added
     *
     * @exception IllegalArgumentException
     *      if any of the Strings in components is null or zero length
     */
    public POIFSDocumentPath(final POIFSDocumentPath path, final String[] components) throws IllegalArgumentException {
        String[] s1 = (path == null) ? new String[0] : path.components;
        String[] s2 = (components == null) ? new String[0] : components;

        // TODO: Although the Javadoc says empty strings are forbidden, the adapted legacy
        //  implementation allowed it in case a path was specified...
        Predicate<String> p = (path != null) ? Objects::isNull : (s) -> (s == null || s.isEmpty());
        if (Stream.of(s2).anyMatch(p)) {
            throw new IllegalArgumentException("components cannot contain null or empty strings");
        }

        this.components = Stream.concat(Stream.of(s1),Stream.of(s2)).toArray(String[]::new);
    }

    /**
     * Two POIFSDocumentPath instances are equal if they have the same number of component Strings,
     * and if each component String is equal to its corresponding component String
     *
     * @param o the object we're checking equality for
     *
     * @return true if the object is equal to this object
     */

    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }

        if ((o != null) && (o.getClass() == this.getClass())) {
            POIFSDocumentPath path = ( POIFSDocumentPath ) o;
            return Arrays.equals(this.components, path.components);
        }
        return false;
    }

    /**
     * calculate and return the hashcode
     *
     * @return hashcode
     */

    public int hashCode() {
        return (hashcode == 0) ? (hashcode = Arrays.hashCode(components)) : hashcode;
    }

    /**
     * @return the number of components
     */
    public int length() {
        return components.length;
    }

    /**
     * get the specified component
     *
     * @param n which component (0 ... length() - 1)
     *
     * @return the nth component;
     *
     * @exception ArrayIndexOutOfBoundsException if n &lt; 0 or n >= length()
     */
    public String getComponent(int n) throws ArrayIndexOutOfBoundsException {
        return components[ n ];
    }

    /**
     * <p>Returns the path's parent or <code>null</code> if this path
     * is the root path.</p>
     *
     * @since 2002-01-24
     * @return path of parent, or null if this path is the root path
     */
    public POIFSDocumentPath getParent() {
        return (components.length == 0) ? null : new POIFSDocumentPath(Arrays.copyOf(components, components.length - 1));
    }

    /**
     * <p>Returns the last name in the document path's name sequence.
     * If the document path's name sequence is empty, then the empty string is returned.</p>
     *
     * @since 2016-04-09
     * @return The last name in the document path's name sequence, or empty string if this is the root path
     */
    public String getName() {
        return components.length == 0 ? "" : components[components.length - 1];
    }

    /**
     * <p>Returns a string representation of the path. Components are
     * separated by the platform-specific file separator {@link File#separatorChar}</p>
     *
     * @return string representation
     *
     * @since 2002-01-24
     */
    public String toString() {
        return File.separatorChar + String.join(String.valueOf(File.separatorChar), components);
    }
}

