/*
 * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

/* Byron Nevins, April 2000
 * ZipFile -- A utility class for exploding jar files that contain EJB(s).  Used *only* in this package by the EJBImporter class
 */
package com.sun.enterprise.util.zip;

import com.sun.enterprise.util.io.FileListerRelative;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipOutputStream;

public class ZipWriter {
    public ZipWriter(String zipFilename, String dirName) throws ZipFileException {
        init(zipFilename, dirName);
        createItemList(null);
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////////
    public ZipWriter(String zipFilename, String dirName, ZipItem[] theItems) throws ZipFileException {
        items = theItems;
        init(zipFilename, dirName);
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////////
    public ZipWriter(String zipFilename, String dirName, String[] fileList) throws ZipFileException {
        init(zipFilename, dirName);
        createItemList(fileList);
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////////
    public ZipWriter(OutputStream outStream, String dirName, String[] fileList) throws ZipFileException {
        init(outStream, dirName);
        createItemList(fileList);
    }

    /**
     * Exclude any files that are under these directories. E.g. suppose you have
     * C:/temp/x1, C:/temp/x2 and C:/temp/x3 and the root is set to c:temp. Then
     * to exclude the contents of the second 2 dirs you would send in a String
     * array with "x2" and "x3"
     *
     * @param dirs an array of top-level directory names
     */
    public void excludeDirs(String[] dirs) {
        if (dirs == null || dirs.length <= 0)
            return;

        // make sure the names all end with "/"
        for (int i = 0; i < dirs.length; i++) {
            if (!dirs[i].endsWith("/"))
                dirs[i] += "/";
        }

        // copy all the items we will retain into list
        List<ZipItem> list = new ArrayList<ZipItem>(items.length);

        for (int i = 0; i < items.length; i++) {
            boolean exclude = false;

            for (int j = 0; j < dirs.length; j++) {
                if (items[i].name.startsWith(dirs[j])) {
                    exclude = true;
                    break;  // don't waste time looking at more dirs!
                }
            }

            if (!exclude) {
                list.add(items[i]);
            }
        }

        // reset items to the pruned list
        if (list.size() != items.length) {
            items = new ZipItem[list.size()];
            items = list.toArray(items);
        }
    }

    /**
     * Exclude any files that are under these directories. In this case if the
     * dir name matches with ANY directory anywhere in the path -- exclude it.
     * E.g. say you don't want to copy /a/b/c/osgi-cache/*.* then simply call
     * this method with one of the dirs equal to "osgi-cache"
     *
     * @param dirs an array of directory names
     * @since 4.0
     */
    public void excludeDirsAnywhere(String[] dirs) {
        if (dirs == null || dirs.length <= 0)
            return;
        // make sure the names all start and end with "/"
        for (int i = 0; i < dirs.length; i++) {
            if (!dirs[i].startsWith("/"))
                dirs[i] = "/" + dirs[i];
            if (!dirs[i].endsWith("/"))
                dirs[i] += "/";
        }

        // copy all the items we will retain into list
        List<ZipItem> list = new ArrayList<ZipItem>(items.length);

        for (int i = 0; i < items.length; i++) {
            boolean exclude = false;
            String item = "/" + items[i].name;

            for (int j = 0; j < dirs.length; j++) {
                if (item.indexOf(dirs[j]) >= 0) {
                    exclude = true;
                    break;  // don't waste time looking at more dirs!
                }
            }

            if (!exclude) {
                list.add(items[i]);
            }

        }
        // reset items to the pruned list
        if (list.size() != items.length) {
            items = new ZipItem[list.size()];
            items = list.toArray(items);
        }
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    private void init(String outFileName, String dirName) throws ZipFileException {
        try {
            // ambiguous overload of the 2 init methods if the first arg is plain null.
            init((OutputStream)null, dirName);
            userOutFile = new File(outFileName);
        }
        catch (Exception e) {
            throw new ZipFileException(e);
        }
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    private void close() {
        // close the stream in ALL cases -- even if the caller sent in the already-made stream
        try {
            if (zipStream != null)
                zipStream.close();
        }
        catch (Exception e) {
            // nothing can be done about it.
        }
        zipStream = null;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    private void init(OutputStream outStream, String dirName) throws ZipFileException {
        try {
            userStream = outStream; // might be null

            if (dirName == null)
                throw new IllegalArgumentException("null dirName");

            //make sure it's really a directory
            File f = new File(dirName);

            if (!f.exists())
                throw new ZipFileException("directory (" + dirName + ") doesn't exist");

            if (!f.isDirectory())
                throw new ZipFileException(dirName + " is not a directory");

            // change the filename to be full-path & UNIX style
            try {
                dirName = f.getCanonicalPath();
            }
            catch (IOException e) {
                dirName = f.getAbsolutePath();
            }

            dirName = dirName.replace('\\', '/');    // all UNIX-style filenames...


            // we need the dirname to end in a '/'
            if (!dirName.endsWith("/"))
                dirName += "/";

            this.dirName = dirName;
        }
        catch (ZipFileException zfe) {
            throw zfe;
        }
        catch (Throwable t) {
            throw new ZipFileException(t);
        }
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /**
     * Does not throw an exception when there is a duplicate zip entry.
     *
     * @throws ZipFileException if an error while creating the archive
     */
    public void safeWrite() throws ZipFileException {
        try {
            setupZipStream();
            for (int i = 0; i < items.length; i++) {
                try {
                    addEntry(items[i]);
                }
                catch (ZipException e) {
                    // ignore - duplicate zip entry
                }
            }
        }
        catch (ZipFileException z) {
            throw z;
        }
        catch (Exception e) {
            throw new ZipFileException(e);
        }
        finally {
            close();
        }
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    public void write() throws ZipFileException {
        try {
            setupZipStream();
            for (int i = 0; i < items.length; i++) {
                addEntry(items[i]);
            }
        }
        catch (ZipFileException z) {
            throw z;
        }
        catch (Exception e) {
            throw new ZipFileException(e);
        }
        finally {
            close();
        }
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    private void addEntry(ZipItem item) throws ZipFileException, IOException {
        int totalBytes = 0;
        ZipEntry ze = new ZipEntry(item.name);

        zipStream.putNextEntry(ze);
        if (!item.name.endsWith("/")) {
            FileInputStream in = new FileInputStream(item.file);

            try {
                for (int numBytes = in.read(buffer); numBytes > 0; numBytes = in.read(buffer)) {
                    zipStream.write(buffer, 0, numBytes);
                    totalBytes += numBytes;
                }
            }
            finally {
                if (in != null)
                    try {
                        in.close();
                    }
                    catch (IOException e) {
                    }
            }
        }

        zipStream.closeEntry();
        Logger.getAnonymousLogger().finer("Wrote " + item.name + " to Zip File.  Wrote " + totalBytes + " bytes.");
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    private void createItemList(String[] files) throws ZipFileException {
        try {
            if (files == null) {
                FileListerRelative lister = new FileListerRelative(new File(dirName));
                files = lister.getFiles();
            }

            if (files.length <= 0)
                throw new ZipFileException("No files to add!");

            items = new ZipItem[files.length];

            for (int i = 0; i < files.length; i++) {
                File f = new File(dirName + files[i]);
                items[i] = new ZipItem(f, files[i].replace('\\', '/'));    // just in case...

                // bnevins -- add a trailing "/" to empty directories
                if (f.isDirectory())
                    items[i].name += "/";
            }
        }
        catch (Throwable t) {
            throw new ZipFileException(t);
        }

    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    String getDirName() {
        return dirName;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    private static void usage() {
        System.out.println("usage: java com.elf.util.zip.ZipWriter zip-filename directory-name");
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    public static void main(String[] args) {
        if (args == null || args.length != 2) {
            usage();
            return;
        }

        try {
            ZipWriter zw = new ZipWriter(args[0], args[1]);
            zw.write();
        }
        catch (ZipFileException e) {
            // nothing to do.
        }
    }

    /////////////////////////////////////////////////////////////////////////////////////////
    private void setupZipStream() throws FileNotFoundException {
        // 2 cases, either user supplied an output filename or an output stream
        if(userStream != null)
            zipStream = new ZipOutputStream(userStream);
        else
            zipStream = new ZipOutputStream(new FileOutputStream(userOutFile));
    }
    /////////////////////////////////////////////////////////////////////////////////////////
    //private                    String            zipFilename        = null;
    private String dirName = null;
    private OutputStream userStream;
    private File userOutFile;
    private ZipOutputStream zipStream;
    private byte[] buffer = new byte[16384];
    private ZipItem[] items = null;

}
