/*
 * ProGuard -- shrinking, optimization, obfuscation, and preverification
 *             of Java bytecode.
 *
 * Copyright (c) 2002-2014 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 proguard.classfile.ClassPool;
import proguard.classfile.util.WarningPrinter;
import proguard.classfile.visitor.*;
import proguard.io.*;

import java.io.IOException;

/**
 * This class reads the input class files.
 *
 * @author Eric Lafortune
 */
public class InputReader
{
    private final Configuration configuration;


    /**
     * Creates a new InputReader to read input class files as specified by the
     * given configuration.
     */
    public InputReader(Configuration configuration)
    {
        this.configuration = configuration;
    }


    /**
     * Fills the given program class pool and library class pool by reading
     * class files, based on the current configuration.
     */
    public void execute(ClassPool programClassPool,
                        ClassPool libraryClassPool) throws IOException
    {
        WarningPrinter warningPrinter = new WarningPrinter(System.err, configuration.warn);
        WarningPrinter notePrinter    = new WarningPrinter(System.out, configuration.note);

        DuplicateClassPrinter duplicateClassPrinter = new DuplicateClassPrinter(notePrinter);

        // Android-added: Read the classes from the systemjars.
        // These are read into the library ClassPool before the programjars so that any duplicates
        // between these are programjars will result in the classes in the programjars being
        // ignored.
        // Read the system class files, if any.
        if (configuration.systemJars != null)
        {
            // Prepare a data entry reader to filter all classes,
            // which are then decoded to classes by a class reader,
            // which are then filtered by removing any that already exist in the libraryClassPool.
            // which are then put in the class pool by a class pool filler.
            readInput("Reading system ",
                      configuration.systemJars,
                      new ClassFilter(
                      new ClassReader(true /* isLibrary */,
                                      configuration.skipNonPublicLibraryClasses,
                                      configuration.skipNonPublicLibraryClassMembers,
                                      warningPrinter,
                      new ClassPresenceFilter(libraryClassPool, duplicateClassPrinter,
                      new ClassPoolFiller(libraryClassPool)))));
        }

        // Read the program class files.
        // Prepare a data entry reader to filter all classes,
        // which are then decoded to classes by a class reader,
        // which are then put in the class pool by a class pool filler.
        readInput("Reading program ",
                  configuration.programJars,
                  new ClassFilter(
                  new ClassReader(false,
                                  configuration.skipNonPublicLibraryClasses,
                                  configuration.skipNonPublicLibraryClassMembers,
                                  warningPrinter,
                  new ClassPresenceFilter(programClassPool, duplicateClassPrinter,
                  // Android-changed: Filter out classes already read from systemjars.
                  new ClassPresenceFilter(libraryClassPool, duplicateClassPrinter,
                  new ClassPoolFiller(programClassPool))))));

        // Check if we have at least some input classes.
        if (programClassPool.size() == 0)
        {
            throw new IOException("The input doesn't contain any classes. Did you specify the proper '-injars' options?");
        }

        // Read the library class files, if any.
        if (configuration.libraryJars != null)
        {
            // Prepare a data entry reader to filter all classes,
            // which are then decoded to classes by a class reader,
            // which are then put in the class pool by a class pool filler.
            readInput("Reading library ",
                      configuration.libraryJars,
                      new ClassFilter(
                      new ClassReader(true,
                                      configuration.skipNonPublicLibraryClasses,
                                      configuration.skipNonPublicLibraryClassMembers,
                                      warningPrinter,
                      new ClassPresenceFilter(programClassPool, duplicateClassPrinter,
                      new ClassPresenceFilter(libraryClassPool, duplicateClassPrinter,
                      new ClassPoolFiller(libraryClassPool))))));
        }

        // Print out a summary of the notes, if necessary.
        int noteCount = notePrinter.getWarningCount();
        if (noteCount > 0)
        {
            System.err.println("Note: there were " + noteCount +
                               " duplicate class definitions.");
            System.err.println("      (http://proguard.sourceforge.net/manual/troubleshooting.html#duplicateclass)");
        }

        // Print out a summary of the warnings, if necessary.
        int warningCount = warningPrinter.getWarningCount();
        if (warningCount > 0)
        {
            System.err.println("Warning: there were " + warningCount +
                               " classes in incorrectly named files.");
            System.err.println("         You should make sure all file names correspond to their class names.");
            System.err.println("         The directory hierarchies must correspond to the package hierarchies.");
            System.err.println("         (http://proguard.sourceforge.net/manual/troubleshooting.html#unexpectedclass)");

            if (!configuration.ignoreWarnings)
            {
                System.err.println("         If you don't mind the mentioned classes not being written out,");
                System.err.println("         you could try your luck using the '-ignorewarnings' option.");
                throw new IOException("Please correct the above warnings first.");
            }
        }
    }


    /**
     * Reads all input entries from the given class path.
     */
    private void readInput(String          messagePrefix,
                           ClassPath       classPath,
                           DataEntryReader reader) throws IOException
    {
        readInput(messagePrefix,
                  classPath,
                  0,
                  classPath.size(),
                  reader);
    }


    /**
     * Reads all input entries from the given section of the given class path.
     */
    public void readInput(String          messagePrefix,
                          ClassPath       classPath,
                          int             fromIndex,
                          int             toIndex,
                          DataEntryReader reader) throws IOException
    {
        for (int index = fromIndex; index < toIndex; index++)
        {
            ClassPathEntry entry = classPath.get(index);
            if (!entry.isOutput())
            {
                readInput(messagePrefix, entry, reader);
            }
        }
    }


    /**
     * Reads the given input class path entry.
     */
    private void readInput(String          messagePrefix,
                           ClassPathEntry  classPathEntry,
                           DataEntryReader dataEntryReader) throws IOException
    {
        try
        {
            // Create a reader that can unwrap jars, wars, ears, and zips.
            DataEntryReader reader =
                DataEntryReaderFactory.createDataEntryReader(messagePrefix,
                                                             classPathEntry,
                                                             dataEntryReader);

            // Create the data entry pump.
            DirectoryPump directoryPump =
                new DirectoryPump(classPathEntry.getFile());

            // Pump the data entries into the reader.
            directoryPump.pumpDataEntries(reader);
        }
        catch (IOException ex)
        {
            throw (IOException)new IOException("Can't read [" + classPathEntry + "] (" + ex.getMessage() + ")").initCause(ex);
        }
    }
}
