/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Ant", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
package org.apache.tools.ant.taskdefs;

import java.io.*;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.zip.CRC32;
import java.util.zip.ZipInputStream;
import org.apache.tools.ant.*;
import org.apache.tools.ant.types.*;
import org.apache.tools.ant.util.*;
import org.apache.tools.zip.*;

/**
 * Create a ZIP archive.
 *
 * @author James Davidson <a href="mailto:duncan@x180.com">duncan@x180.com</a>
 * @author Jon S. Stevens <a href="mailto:jon@clearink.com">jon@clearink.com</a>
 * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
 */
public class Zip extends MatchingTask {

    private File zipFile;
    private File baseDir;
    private boolean doCompress = true;
    private boolean doUpdate = false;
    private boolean doFilesonly = false;
    protected String archiveType = "zip";
    // For directories:
    private static long emptyCrc = new CRC32 ().getValue ();
    protected String emptyBehavior = "skip";
    private Vector filesets = new Vector ();
    private Hashtable addedDirs = new Hashtable();
    private Vector addedFiles = new Vector();
    
    /** true when we are adding new files into the Zip file, as opposed to 
        adding back the unchanged files */
    private boolean addingNewFiles;
    
    
    /**
     * Encoding to use for filenames, defaults to the platform's
     * default encoding.
     */
    private String encoding = null;

    /**
     * This is the name/location of where to 
     * create the .zip file.
     */
    public void setZipfile(File zipFile) {
        this.zipFile = zipFile;
    }
    
    /**
     * This is the base directory to look in for 
     * things to zip.
     */
    public void setBasedir(File baseDir) {
        this.baseDir = baseDir;
    }

    /**
     * Sets whether we want to compress the files or only store them.
     */
    public void setCompress(boolean c) {
        doCompress = c;
    }

    /**
     * Emulate Sun's jar utility by not adding parent dirs
     */
    public void setFilesonly(boolean f) {
        doFilesonly = f;
    }

    /**
     * Sets whether we want to update the file (if it exists)
     * or create a new one.
     */
    public void setUpdate(boolean c) {
        doUpdate = c;
    }

    /**
     * Adds a set of files (nested fileset attribute).
     */
    public void addFileset(FileSet set) {
        filesets.addElement(set);
    }

    /**
     * Adds a set of files (nested zipfileset attribute) that can be
     * read from an archive and be given a prefix/fullpath.
     */
    public void addZipfileset(ZipFileSet set) {
        filesets.addElement(set);
    }


    /** Possible behaviors when there are no matching files for the task. */
    public static class WhenEmpty extends EnumeratedAttribute {
        public String[] getValues() {
            return new String[] {"fail", "skip", "create"};
        }
    }

    /**
     * Sets behavior of the task when no files match.
     * Possible values are: <code>fail</code> (throw an exception
     * and halt the build); <code>skip</code> (do not create
     * any archive, but issue a warning); <code>create</code>
     * (make an archive with no entries).
     * Default for zip tasks is <code>skip</code>;
     * for jar tasks, <code>create</code>.
     */
    public void setWhenempty(WhenEmpty we) {
        emptyBehavior = we.getValue();
    }

    /**
     * Encoding to use for filenames, defaults to the platform's
     * default encoding.
     *
     * <p>For a list of possible values see <a
     * href="http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.html">http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.html</a>.</p>
     */
    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

    public void execute() throws BuildException {
        if (baseDir == null && filesets.size() == 0 && "zip".equals(archiveType)) {
            throw new BuildException( "basedir attribute must be set, or at least " + 
                                      "one fileset must be given!" );
        }

        if (zipFile == null) {
            throw new BuildException("You must specify the " + archiveType + " file to create!");
        }

        // Renamed version of original file, if it exists
        File renamedFile = null;
        // Whether or not an actual update is required -
        // we don't need to update if the original file doesn't exist
        
        addingNewFiles = true;
        boolean reallyDoUpdate = false;
        if (doUpdate && zipFile.exists())
        {
            reallyDoUpdate = true;
            
            int i;
            for (i=0; i < 1000; i++)
            {
                renamedFile = new File(zipFile.getParent(), "tmp."+i);
                
                if (!renamedFile.exists()) {
                    break;
                }
            }
            if (i == 1000) {
                throw new BuildException("Can't find available temporary filename to which to rename old file.");
            }
            
            try
            {
                if (!zipFile.renameTo(renamedFile)) {
                    throw new BuildException("Unable to rename old file to temporary file");
                }
            }
            catch (SecurityException e)
            {
                throw new BuildException("Not allowed to rename old file to temporary file");
            }
        }
        
        // Create the scanners to pass to isUpToDate().
        Vector dss = new Vector ();
        if (baseDir != null) {
            dss.addElement(getDirectoryScanner(baseDir));
        }
        for (int i=0; i<filesets.size(); i++) {
            FileSet fs = (FileSet) filesets.elementAt(i);
            dss.addElement (fs.getDirectoryScanner(project));
        }
        int dssSize = dss.size();
        FileScanner[] scanners = new FileScanner[dssSize];
        dss.copyInto(scanners);

        // quick exit if the target is up to date
        // can also handle empty archives
        if (isUpToDate(scanners, zipFile)) {
            return;
        }

        String action = reallyDoUpdate ? "Updating " : "Building ";
        
        log(action + archiveType +": "+ zipFile.getAbsolutePath());

        boolean success = false;
        try {
            ZipOutputStream zOut = 
              new ZipOutputStream(new FileOutputStream(zipFile));
            zOut.setEncoding(encoding);
            try {
                if (doCompress) {
                    zOut.setMethod(ZipOutputStream.DEFLATED);
                } else {
                    zOut.setMethod(ZipOutputStream.STORED);
                }
                initZipOutputStream(zOut);

                // Add the implicit fileset to the archive.
                if (baseDir != null) {
                    addFiles(getDirectoryScanner(baseDir), zOut, "", "");
                }
                // Add the explicit filesets to the archive.
                addFiles(filesets, zOut);
                if (reallyDoUpdate) {
                    addingNewFiles = false;
                    ZipFileSet oldFiles = new ZipFileSet();
                    oldFiles.setSrc(renamedFile);
                    
                    StringBuffer exclusionPattern = new StringBuffer();
                    for (int i=0; i < addedFiles.size(); i++)
                    {
                        if (i != 0) {
                            exclusionPattern.append(",");
                        }
                        exclusionPattern.append((String)addedFiles.elementAt(i));
                    }
                    oldFiles.setExcludes(exclusionPattern.toString());
                    Vector tmp = new Vector();
                    tmp.addElement(oldFiles);
                    addFiles(tmp, zOut);
                }
                finalizeZipOutputStream(zOut);
                success = true;
            } finally {
                // Close the output stream.
                try {
                    if (zOut != null) {
                        zOut.close();
                    }
                } catch(IOException ex) {
                    // If we're in this finally clause because of an exception, we don't 
                    // really care if there's an exception when closing the stream. E.g. if it
                    // throws "ZIP file must have at least one entry", because an exception happened
                    // before we added any files, then we must swallow this exception. Otherwise,
                    // the error that's reported will be the close() error, which is not the real 
                    // cause of the problem.
                    if (success)
                        throw ex;
                }
            }
        } catch (IOException ioe) {
            String msg = "Problem creating " + archiveType + ": " + ioe.getMessage();

            // delete a bogus ZIP file
            if (!zipFile.delete()) {
                msg += " (and the archive is probably corrupt but I could not delete it)";
            }

            if (reallyDoUpdate) {
                if (!renamedFile.renameTo(zipFile)) {
                    msg+=" (and I couldn't rename the temporary file "+
                        renamedFile.getName()+" back)";
                }
            }
            
            throw new BuildException(msg, ioe, location);
        } finally {
            cleanUp();
        }
        
        // If we've been successful on an update, delete the temporary file
        if (success && reallyDoUpdate) {
            if (!renamedFile.delete()) {
                log ("Warning: unable to delete temporary file " +
                     renamedFile.getName(), Project.MSG_WARN);
            }
        }
    }

    /**
     * Indicates if the task is adding new files into the archive as opposed to
     * copying back unchanged files from the backup copy
     */
    protected boolean isAddingNewFiles() {
        return addingNewFiles;
    }
    
    /**
     * Add all files of the given FileScanner to the ZipOutputStream
     * prependig the given prefix to each filename.
     *
     * <p>Ensure parent directories have been added as well.  
     */
    protected void addFiles(FileScanner scanner, ZipOutputStream zOut, 
                            String prefix, String fullpath) throws IOException {
        if (prefix.length() > 0 && fullpath.length() > 0)
             throw new BuildException("Both prefix and fullpath attributes may not be set on the same fileset.");

        File thisBaseDir = scanner.getBasedir();

        // directories that matched include patterns
        String[] dirs = scanner.getIncludedDirectories();
        if (dirs.length > 0 && fullpath.length() > 0)
            throw new BuildException("fullpath attribute may only be specified for filesets that specify a single file.");
        for (int i = 0; i < dirs.length; i++) {
            if ("".equals(dirs[i])) {
                continue;
            }
            String name = dirs[i].replace(File.separatorChar,'/');
            if (!name.endsWith("/")) {
                name += "/";
            }
            addParentDirs(thisBaseDir, name, zOut, prefix);
        }

        // files that matched include patterns
        String[] files = scanner.getIncludedFiles();
         if (files.length > 1 && fullpath.length() > 0)
            throw new BuildException("fullpath attribute may only be specified for filesets that specify a single file.");
        for (int i = 0; i < files.length; i++) {
            File f = new File(thisBaseDir, files[i]);
            if (fullpath.length() > 0)
            {
                // Add this file at the specified location.
                addParentDirs(null, fullpath, zOut, "");
                zipFile(f, zOut, fullpath);
            }
            else
            {
                // Add this file with the specified prefix.
                String name = files[i].replace(File.separatorChar,'/');
                addParentDirs(thisBaseDir, name, zOut, prefix);
                zipFile(f, zOut, prefix+name);
            }
        }
    }

    protected void addZipEntries(ZipFileSet fs, DirectoryScanner ds,
      ZipOutputStream zOut, String prefix)
        throws IOException
    {
        ZipScanner zipScanner = (ZipScanner) ds;
        File zipSrc = fs.getSrc();

        ZipEntry entry;
        java.util.zip.ZipEntry origEntry;
        ZipInputStream in = null;
        try {
            in = new ZipInputStream(new FileInputStream(zipSrc));

            while ((origEntry = in.getNextEntry()) != null) {
                entry = new ZipEntry(origEntry);
                String vPath = entry.getName();
                if (zipScanner.match(vPath)) {
                    addParentDirs(null, vPath, zOut, prefix);
                    if (! entry.isDirectory()) {
                        zipFile(in, zOut, prefix+vPath, entry.getTime());
                    }
                }
            }
        } finally {
            if (in != null) {
                in.close();
            }
        }
    }

    protected void initZipOutputStream(ZipOutputStream zOut)
        throws IOException, BuildException
    {
    }

    protected void finalizeZipOutputStream(ZipOutputStream zOut)
        throws IOException, BuildException
    {
    }

    /**
     * Create an empty zip file
     *
     * @return true if the file is then considered up to date.
     */
    protected boolean createEmptyZip(File zipFile) {
        // In this case using java.util.zip will not work
        // because it does not permit a zero-entry archive.
        // Must create it manually.
        log("Note: creating empty "+archiveType+" archive " + zipFile, Project.MSG_INFO);
        try {
            OutputStream os = new FileOutputStream(zipFile);
            try {
                // Cf. PKZIP specification.
                byte[] empty = new byte[22];
                empty[0] = 80; // P
                empty[1] = 75; // K
                empty[2] = 5;
                empty[3] = 6;
                // remainder zeros
                os.write(empty);
            } finally {
                os.close();
            }
        } catch (IOException ioe) {
            throw new BuildException("Could not create empty ZIP archive", ioe, location);
        }
        return true;
    }
    
    
    /**
     * Check whether the archive is up-to-date; and handle behavior for empty archives.
     * @param scanners list of prepared scanners containing files to archive
     * @param zipFile intended archive file (may or may not exist)
     * @return true if nothing need be done (may have done something already); false if
     *         archive creation should proceed
     * @exception BuildException if it likes
     */
    protected boolean isUpToDate(FileScanner[] scanners, File zipFile) throws BuildException
    {
        String[][] fileNames = grabFileNames(scanners);
        File[] files = grabFiles(scanners, fileNames);
        if (files.length == 0) {
            if (emptyBehavior.equals("skip")) {
                log("Warning: skipping "+archiveType+" archive " + zipFile +
                    " because no files were included.", Project.MSG_WARN);
                return true;
            } else if (emptyBehavior.equals("fail")) {
                throw new BuildException("Cannot create "+archiveType+" archive " + zipFile +
                                         ": no files were included.", location);
            } else {
                // Create.
                return createEmptyZip(zipFile);
            }
        } else {
            for (int i = 0; i < files.length; ++i) {
                if (files[i].equals(zipFile)) {
                    throw new BuildException("A zip file cannot include itself", location);
                }
            }

            if (!zipFile.exists()) return false;

            SourceFileScanner sfs = new SourceFileScanner(this);
            MergingMapper mm = new MergingMapper();
            mm.setTo(zipFile.getAbsolutePath());
            for (int i=0; i<scanners.length; i++) {
                if (sfs.restrict(fileNames[i], scanners[i].getBasedir(), null,
                                 mm).length > 0) {
                    return false;
                }
            }
            return true;
        }
    }

    protected static File[] grabFiles(FileScanner[] scanners) {
        return grabFiles(scanners, grabFileNames(scanners));
    }

    protected static File[] grabFiles(FileScanner[] scanners, 
                                      String[][] fileNames) {
        Vector files = new Vector();
        for (int i = 0; i < fileNames.length; i++) {
            File thisBaseDir = scanners[i].getBasedir();
            for (int j = 0; j < fileNames[i].length; j++)
                files.addElement(new File(thisBaseDir, fileNames[i][j]));
        }
        File[] toret = new File[files.size()];
        files.copyInto(toret);
        return toret;
    }

    protected static String[][] grabFileNames(FileScanner[] scanners) {
        String[][] result = new String[scanners.length][];
        for (int i=0; i<scanners.length; i++) {
            String[] files = scanners[i].getIncludedFiles();
            String[] dirs = scanners[i].getIncludedDirectories();
            result[i] = new String[files.length + dirs.length];
            System.arraycopy(files, 0, result[i], 0, files.length);
            System.arraycopy(dirs, 0, result[i], files.length, dirs.length);
        }
        return result;
    }

    protected void zipDir(File dir, ZipOutputStream zOut, String vPath)
        throws IOException
    {
        if (addedDirs.get(vPath) != null) {
            // don't add directories we've already added.
            // no warning if we try, it is harmless in and of itself
            return;
        }
        addedDirs.put(vPath, vPath);
        
        ZipEntry ze = new ZipEntry (vPath);
        if (dir != null && dir.exists()) {
            ze.setTime(dir.lastModified());
        } else {
            ze.setTime(System.currentTimeMillis());
        }
        ze.setSize (0);
        ze.setMethod (ZipEntry.STORED);
        // This is faintly ridiculous:
        ze.setCrc (emptyCrc);

        // this is 040775 | MS-DOS directory flag in reverse byte order
        ze.setExternalAttributes(0x41FD0010L);

        zOut.putNextEntry (ze);
    }

    protected void zipFile(InputStream in, ZipOutputStream zOut, String vPath,
                           long lastModified)
        throws IOException
    {
        ZipEntry ze = new ZipEntry(vPath);
        ze.setTime(lastModified);

        /*
         * XXX ZipOutputStream.putEntry expects the ZipEntry to know its
         * size and the CRC sum before you start writing the data when using 
         * STORED mode.
         *
         * This forces us to process the data twice.
         *
         * I couldn't find any documentation on this, just found out by try 
         * and error.
         */
        if (!doCompress) {
            long size = 0;
            CRC32 cal = new CRC32();
            if (!in.markSupported()) {
                // Store data into a byte[]
                ByteArrayOutputStream bos = new ByteArrayOutputStream();

                byte[] buffer = new byte[8 * 1024];
                int count = 0;
                do {
                    size += count;
                    cal.update(buffer, 0, count);
                    bos.write(buffer, 0, count);
                    count = in.read(buffer, 0, buffer.length);
                } while (count != -1);
                in = new ByteArrayInputStream(bos.toByteArray());

            } else {
                in.mark(Integer.MAX_VALUE);
                byte[] buffer = new byte[8 * 1024];
                int count = 0;
                do {
                    size += count;
                    cal.update(buffer, 0, count);
                    count = in.read(buffer, 0, buffer.length);
                } while (count != -1);
                in.reset();
            }
            ze.setSize(size);
            ze.setCrc(cal.getValue());
        }

        zOut.putNextEntry(ze);

        byte[] buffer = new byte[8 * 1024];
        int count = 0;
        do {
            if (count != 0) {
                zOut.write(buffer, 0, count);
            }
            count = in.read(buffer, 0, buffer.length);
        } while (count != -1);
        addedFiles.addElement(vPath);
    }

    protected void zipFile(File file, ZipOutputStream zOut, String vPath)
        throws IOException
    {
        if (file.equals(zipFile)) {
            throw new BuildException("A zip file cannot include itself", location);
        }

        FileInputStream fIn = new FileInputStream(file);
        try {
            zipFile(fIn, zOut, vPath, file.lastModified());
        } finally {
            fIn.close();
        }
    }

    /**
     * Ensure all parent dirs of a given entry have been added.
     */
    protected void addParentDirs(File baseDir, String entry,
                                 ZipOutputStream zOut, String prefix)
        throws IOException {
        if( !doFilesonly ) {
            Stack directories = new Stack();
            int slashPos = entry.length();
            
            while ((slashPos = entry.lastIndexOf((int)'/', slashPos-1)) != -1) {
                String dir = entry.substring(0, slashPos+1);
                if (addedDirs.get(prefix+dir) != null) {
                    break;
                }
                directories.push(dir);
            }
            
            while (!directories.isEmpty()) {
                String dir = (String) directories.pop();
                File f = null;
                if (baseDir != null) {
                    f = new File(baseDir, dir);
                } else {
                    f = new File(dir);
                }
                zipDir(f, zOut, prefix+dir);
            }
        }
    }

    /**
     * Iterate over the given Vector of (zip)filesets and add
     * all files to the ZipOutputStream using the given prefix.
     */
    protected void addFiles(Vector filesets, ZipOutputStream zOut)
        throws IOException {
        // Add each fileset in the Vector.
        for (int i = 0; i<filesets.size(); i++) {
            FileSet fs = (FileSet) filesets.elementAt(i);
            DirectoryScanner ds = fs.getDirectoryScanner(project);

            String prefix = "";
            String fullpath = "";
            if (fs instanceof ZipFileSet) {
                ZipFileSet zfs = (ZipFileSet) fs;
                prefix = zfs.getPrefix();
                fullpath = zfs.getFullpath();
            }
            
            if (prefix.length() > 0 
                && !prefix.endsWith("/")
                && !prefix.endsWith("\\")) {
                prefix += "/";
            }

            // Need to manually add either fullpath's parent directory, or 
            // the prefix directory, to the archive. 
            if (prefix.length() > 0) {
                addParentDirs(null, prefix, zOut, "");
                zipDir(null, zOut, prefix);
            } else if (fullpath.length() > 0) {
                addParentDirs(null, fullpath, zOut, "");
            }

            if (fs instanceof ZipFileSet
                && ((ZipFileSet) fs).getSrc() != null) {
                addZipEntries((ZipFileSet) fs, ds, zOut, prefix);
            } else {
                // Add the fileset.
                addFiles(ds, zOut, prefix, fullpath);
            }
        }
    }

    /**
     * Do any clean up necessary to allow this instance to be used again.
     *
     * <p>When we get here, the Zip file has been closed and all we
     * need to do is to reset some globals.</p>
     */
    protected void cleanUp() {
        addedDirs = new Hashtable();
        addedFiles = new Vector();
    }
}
