/*
 * ProGuard -- shrinking, optimization, obfuscation, and preverification
 *             of Java bytecode.
 *
 * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
 *
 * 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 == '"';
    }
}
