/*
 *  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
 *
 *      https://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.tools.ant;

import java.io.File;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;

import org.apache.tools.ant.taskdefs.condition.Os;

/**
 * A Path tokenizer takes a path and returns the components that make up
 * that path.
 *
 * The path can use path separators of either ':' or ';' and file separators
 * of either '/' or '\'.
 *
 */
public class PathTokenizer {
    /**
     * A tokenizer to break the string up based on the ':' or ';' separators.
     */
    private StringTokenizer tokenizer;

    /**
     * A String which stores any path components which have been read ahead
     * due to DOS filesystem compensation.
     */
    private String lookahead = null;

    /**
     * A boolean that determines if we are running on Novell NetWare, which
     * exhibits slightly different path name characteristics (multi-character
     * volume / drive names)
     */
    private boolean onNetWare = Os.isFamily("netware");

    /**
     * Flag to indicate whether or not we are running on a platform with a
     * DOS style filesystem
     */
    private boolean dosStyleFilesystem;

    /**
     * Constructs a path tokenizer for the specified path.
     *
     * @param path The path to tokenize. Must not be <code>null</code>.
     */
    public PathTokenizer(String path) {
        if (onNetWare) {
            // For NetWare, use the boolean=true mode, so we can use delimiter
            // information to make a better decision later.
            tokenizer = new StringTokenizer(path, ":;", true);
        } else {
            // on Windows and Unix, we can ignore delimiters and still have
            // enough information to tokenize correctly.
            tokenizer = new StringTokenizer(path, ":;", false);
        }
        dosStyleFilesystem = File.pathSeparatorChar == ';';
    }

    /**
     * Tests if there are more path elements available from this tokenizer's
     * path. If this method returns <code>true</code>, then a subsequent call
     * to nextToken will successfully return a token.
     *
     * @return <code>true</code> if and only if there is at least one token
     * in the string after the current position; <code>false</code> otherwise.
     */
    public boolean hasMoreTokens() {
        return lookahead != null || tokenizer.hasMoreTokens();
    }

    /**
     * Returns the next path element from this tokenizer.
     *
     * @return the next path element from this tokenizer.
     *
     * @exception NoSuchElementException if there are no more elements in this
     *            tokenizer's path.
     */
    public String nextToken() throws NoSuchElementException {
        String token = null;
        if (lookahead != null) {
            token = lookahead;
            lookahead = null;
        } else {
            token = tokenizer.nextToken().trim();
        }

        if (!onNetWare) {
            if (token.length() == 1 && Character.isLetter(token.charAt(0))
                                    && dosStyleFilesystem
                                    && tokenizer.hasMoreTokens()) {
                // we are on a dos style system so this path could be a drive
                // spec. We look at the next token
                String nextToken = tokenizer.nextToken().trim();
                if (nextToken.startsWith("\\") || nextToken.startsWith("/")) {
                    // we know we are on a DOS style platform and the next path
                    // starts with a slash or backslash, so we know this is a
                    // drive spec
                    token += ":" + nextToken;
                } else {
                    // store the token just read for next time
                    lookahead = nextToken;
                }
            }
        } else {
            // we are on NetWare, tokenizing is handled a little differently,
            // due to the fact that NetWare has multiple-character volume names.
            if (token.equals(File.pathSeparator) || ":".equals(token)) {
                // ignore ";" and get the next token
                token = tokenizer.nextToken().trim();
            }

            if (tokenizer.hasMoreTokens()) {
                // this path could be a drive spec, so look at the next token
                String nextToken = tokenizer.nextToken().trim();

                // make sure we aren't going to get the path separator next
                if (!nextToken.equals(File.pathSeparator)) {
                    if (":".equals(nextToken)) {
                        if (!token.startsWith("/") && !token.startsWith("\\")
                            && !token.startsWith(".")
                            && !token.startsWith("..")) {
                            // it indeed is a drive spec, get the next bit
                            String oneMore = tokenizer.nextToken().trim();
                            if (!oneMore.equals(File.pathSeparator)) {
                                token += ":" + oneMore;
                            } else {
                                token += ":";
                                lookahead = oneMore;
                            }
                        }
                        // implicit else: ignore the ':' since we have either a
                        // UNIX or a relative path
                    } else {
                        // store the token just read for next time
                        lookahead = nextToken;
                    }
                }
            }
        }
        return token;
    }
}
