
/* ====================================================================
   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 &gt; 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 &gt;= 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);
    }
}

