/*
 * 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.File;

/**
 * This class checks whether the output is up to date.
 *
 * @author Eric Lafortune
 */
public class UpToDateChecker
{
    private final Configuration configuration;


    /**
     * Creates a new UpToDateChecker with the given configuration.
     */
    public UpToDateChecker(Configuration configuration)
    {
        this.configuration = configuration;
    }


    /**
     * Returns whether the output is up to date, based on the modification times
     * of the input jars, output jars, and library jars (or directories).
     */
    public boolean check()
    {
        try
        {
            ModificationTimeChecker checker = new ModificationTimeChecker();

            checker.updateInputModificationTime(configuration.lastModified);

            ClassPath programJars = configuration.programJars;
            ClassPath libraryJars = configuration.libraryJars;

            // Check the dates of the program jars, if any.
            if (programJars != null)
            {
                for (int index = 0; index < programJars.size(); index++)
                {
                    // Update the input and output modification times.
                    ClassPathEntry classPathEntry = programJars.get(index);

                    checker.updateModificationTime(classPathEntry.getFile(),
                                                   classPathEntry.isOutput());
                }
            }

            // Check the dates of the library jars, if any.
            if (libraryJars != null)
            {
                for (int index = 0; index < libraryJars.size(); index++)
                {
                    // Update the input modification time.
                    ClassPathEntry classPathEntry = libraryJars.get(index);

                    checker.updateModificationTime(classPathEntry.getFile(),
                                                   false);
                }
            }

            // Check the dates of the auxiliary input files.
            checker.updateInputModificationTime(configuration.applyMapping);
            checker.updateInputModificationTime(configuration.obfuscationDictionary);
            checker.updateInputModificationTime(configuration.classObfuscationDictionary);
            checker.updateInputModificationTime(configuration.packageObfuscationDictionary);

            // Check the dates of the auxiliary output files.
            checker.updateOutputModificationTime(configuration.printSeeds);
            checker.updateOutputModificationTime(configuration.printUsage);
            checker.updateOutputModificationTime(configuration.printMapping);
            checker.updateOutputModificationTime(configuration.printConfiguration);
            checker.updateOutputModificationTime(configuration.dump);
        }
        catch (IllegalStateException e)
        {
            // The output is outdated.
            return false;
        }

        System.out.println("The output seems up to date");

        return true;
    }


    /**
     * This class maintains the modification times of input and output.
     * The methods throw an IllegalStateException if the output appears
     * outdated.
     */
    private static class ModificationTimeChecker {

        private long inputModificationTime  = Long.MIN_VALUE;
        private long outputModificationTime = Long.MAX_VALUE;


        /**
         * Updates the input modification time based on the given file or
         * directory (recursively).
         */
        public void updateInputModificationTime(File file)
        {
            if (file != null)
            {
                updateModificationTime(file, false);
            }
        }


        /**
         * Updates the input modification time based on the given file or
         * directory (recursively).
         */
        public void updateOutputModificationTime(File file)
        {
            if (file != null && file.getName().length() > 0)
            {
                updateModificationTime(file, true);
            }
        }


        /**
         * Updates the specified modification time based on the given file or
         * directory (recursively).
         */
        public void updateModificationTime(File file, boolean isOutput)
        {
            // Is it a directory?
            if (file.isDirectory())
            {
                // Ignore the directory's modification time; just recurse on
                // its files.
                File[] files = file.listFiles();

                // Still, an empty output directory is probably a sign that it
                // is not up to date.
                if (files.length == 0 && isOutput)
                {
                    updateOutputModificationTime(Long.MIN_VALUE);
                }

                for (int index = 0; index < files.length; index++)
                {
                    updateModificationTime(files[index], isOutput);
                }
            }
            else
            {
                // Update with the file's modification time.
                updateModificationTime(file.lastModified(), isOutput);
            }
        }


        /**
         * Updates the specified modification time.
         */
        public void updateModificationTime(long time, boolean isOutput)
        {
            if (isOutput)
            {
                updateOutputModificationTime(time);
            }
            else
            {
                updateInputModificationTime(time);
            }
        }


        /**
         * Updates the input modification time.
         */
        public void updateInputModificationTime(long time)
        {
            if (inputModificationTime < time)
            {
                inputModificationTime = time;

                checkModificationTimes();
            }
        }


        /**
         * Updates the output modification time.
         */
        public void updateOutputModificationTime(long time)
        {
            if (outputModificationTime > time)
            {
                outputModificationTime = time;

                checkModificationTimes();
            }
        }


        private void checkModificationTimes()
        {
            if (inputModificationTime > outputModificationTime)
            {
                throw new IllegalStateException("The output is outdated");
            }
        }
    }
}
