/*
 * ProGuard -- shrinking, optimization, obfuscation, and preverification
 *             of Java bytecode.
 *
 * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package proguard;

import java.io.*;


/**
 * An abstract reader of words, with the possibility to include other readers.
 * Words are separated by spaces or broken off at delimiters. Words containing
 * spaces or delimiters can be quoted with single or double quotes.
 * Comments (everything starting with '#' on a single line) are ignored.
 *
 * @author Eric Lafortune
 * @noinspection TailRecursion
 */
public abstract class WordReader
{
    private static final char COMMENT_CHARACTER = '#';


    private File       baseDir;
    private WordReader includeWordReader;
    private String     currentLine;
    private int        currentLineLength;
    private int        currentIndex;
    private String     currentWord;
    private String     currentComments;


    /**
     * Creates a new WordReader with the given base directory.
     */
    protected WordReader(File baseDir)
    {
        this.baseDir = baseDir;
    }


    /**
     * Sets the base directory of this reader.
     */
    public void setBaseDir(File baseDir)
    {
        if (includeWordReader != null)
        {
            includeWordReader.setBaseDir(baseDir);
        }
        else
        {
            this.baseDir = baseDir;
        }
    }


    /**
     * Returns the base directory of this reader, if any.
     */
    public File getBaseDir()
    {
        return includeWordReader != null ?
            includeWordReader.getBaseDir() :
            baseDir;
    }


    /**
     * Specifies to start reading words from the given WordReader. When it is
     * exhausted, this WordReader will continue to provide its own words.
     *
     * @param newIncludeWordReader the WordReader that will start reading words.
     */
    public void includeWordReader(WordReader newIncludeWordReader)
    {
        if (includeWordReader == null)
        {
            includeWordReader = newIncludeWordReader;
        }
        else
        {
            includeWordReader.includeWordReader(newIncludeWordReader);
        }
    }


    /**
     * Reads a word from this WordReader, or from one of its active included
     * WordReader objects.
     *
     * @param isFileName return a complete line (or argument), if the word
     *                      isn't an option (it doesn't start with '-').
     * @return the read word.
     */
    public String nextWord(boolean isFileName) throws IOException
    {
        currentWord = null;

        // See if we have an included reader to produce a word.
        if (includeWordReader != null)
        {
            // Does the included word reader still produce a word?
            currentWord = includeWordReader.nextWord(isFileName);
            if (currentWord != null)
            {
                // Return it if so.
                return currentWord;
            }

            // Otherwise close and ditch the word reader.
            includeWordReader.close();
            includeWordReader = null;
        }

        // Get a word from this reader.

        // Skip any whitespace and comments left on the current line.
        if (currentLine != null)
        {
            // Skip any leading whitespace.
            while (currentIndex < currentLineLength &&
                   Character.isWhitespace(currentLine.charAt(currentIndex)))
            {
                currentIndex++;
            }

            // Skip any comments.
            if (currentIndex < currentLineLength &&
                isComment(currentLine.charAt(currentIndex)))
            {
                currentIndex = currentLineLength;
            }
        }

        // Make sure we have a non-blank line.
        while (currentLine == null || currentIndex == currentLineLength)
        {
            currentLine = nextLine();
            if (currentLine == null)
            {
                return null;
            }

            currentLineLength = currentLine.length();

            // Skip any leading whitespace.
            currentIndex = 0;
            while (currentIndex < currentLineLength &&
                   Character.isWhitespace(currentLine.charAt(currentIndex)))
            {
                currentIndex++;
            }

            // Remember any leading comments.
            if (currentIndex < currentLineLength &&
                isComment(currentLine.charAt(currentIndex)))
            {
                // Remember the comments.
                String comment = currentLine.substring(currentIndex + 1);
                currentComments = currentComments == null ?
                    comment :
                    currentComments + '\n' + comment;

                // Skip the comments.
                currentIndex = currentLineLength;
            }
        }

        // Find the word starting at the current index.
        int startIndex = currentIndex;
        int endIndex;

        char startChar = currentLine.charAt(startIndex);

        if (isQuote(startChar))
        {
            // The next word is starting with a quote character.
            // Skip the opening quote.
            startIndex++;

            // The next word is a quoted character string.
            // Find the closing quote.
            do
            {
                currentIndex++;

                if (currentIndex == currentLineLength)
                {
                    currentWord = currentLine.substring(startIndex-1, currentIndex);
                    throw new IOException("Missing closing quote for "+locationDescription());
                }
            }
            while (currentLine.charAt(currentIndex) != startChar);

            endIndex = currentIndex++;
        }
        else if (isFileName &&
                 !isOption(startChar))
        {
            // The next word is a (possibly optional) file name.
            // Find the end of the line, the first path separator, the first
            // option, or the first comment.
            while (currentIndex < currentLineLength)
            {
                char currentCharacter = currentLine.charAt(currentIndex);
                if (isFileDelimiter(currentCharacter) ||
                    ((isOption(currentCharacter) ||
                      isComment(currentCharacter)) &&
                     Character.isWhitespace(currentLine.charAt(currentIndex-1)))) {
                    break;
                }

                currentIndex++;
            }

            endIndex = currentIndex;

            // Trim any trailing whitespace.
            while (endIndex > startIndex &&
                   Character.isWhitespace(currentLine.charAt(endIndex-1)))
            {
                endIndex--;
            }
        }
        else if (isDelimiter(startChar))
        {
            // The next word is a single delimiting character.
            endIndex = ++currentIndex;
        }
        else
        {
            // The next word is a simple character string.
            // Find the end of the line, the first delimiter, or the first
            // white space.
            while (currentIndex < currentLineLength)
            {
                char currentCharacter = currentLine.charAt(currentIndex);
                if (isDelimiter(currentCharacter)            ||
                    Character.isWhitespace(currentCharacter) ||
                    isComment(currentCharacter)) {
                    break;
                }

                currentIndex++;
            }

            endIndex = currentIndex;
        }

        // Remember and return the parsed word.
        currentWord = currentLine.substring(startIndex, endIndex);

        return currentWord;
    }


    /**
     * Returns the comments collected before returning the last word.
     * Starts collecting new comments.
     *
     * @return the collected comments, or <code>null</code> if there weren't any.
     */
    public String lastComments() throws IOException
    {
        if (includeWordReader == null)
        {
            String comments = currentComments;
            currentComments = null;
            return comments;
        }
        else
        {
            return includeWordReader.lastComments();
        }
    }


    /**
     * Constructs a readable description of the current position in this
     * WordReader and its included WordReader objects.
     *
     * @return the description.
     */
    public String locationDescription()
    {
        return
            (includeWordReader == null ?
                (currentWord == null ?
                    "end of " :
                    "'" + currentWord + "' in " ) :
                (includeWordReader.locationDescription() + ",\n" +
                 "  included from ")) +
            lineLocationDescription();
    }


    /**
     * Reads a line from this WordReader, or from one of its active included
     * WordReader objects.
     *
     * @return the read line.
     */
    protected abstract String nextLine() throws IOException;


    /**
     * Returns a readable description of the current WordReader position.
     *
     * @return the description.
     */
    protected abstract String lineLocationDescription();


    /**
     * Closes the FileWordReader.
     */
    public void close() throws IOException
    {
        // Close and ditch the included word reader, if any.
        if (includeWordReader != null)
        {
            includeWordReader.close();
            includeWordReader = null;
        }
    }


    // Small utility methods.

    private boolean isOption(char character)
    {
        return character == '-';
    }


    private boolean isComment(char character)
    {
        return character == COMMENT_CHARACTER;
    }


    private boolean isDelimiter(char character)
    {
        return character == '@' ||
               character == '{' ||
               character == '}' ||
               character == '(' ||
               character == ')' ||
               character == ',' ||
               character == ';' ||
               character == File.pathSeparatorChar;
    }


    private boolean isFileDelimiter(char character)
    {
        return character == '(' ||
               character == ')' ||
               character == ',' ||
               character == ';' ||
               character == File.pathSeparatorChar;
    }


    private boolean isQuote(char character)
    {
        return character == '\'' ||
               character == '"';
    }
}
