/*
 * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

import java.io.*;
import java.nio.charset.Charset;
import java.util.*;
import java.util.zip.*;
import java.text.MessageFormat;

/**
 * A stripped-down version of Jar tool with a "-encoding" option to
 * support non-UTF8 encoidng for entry name and comment.
 */
public class zip {
    String program;
    PrintStream out, err;
    String fname;
    String zname = "";
    String[] files;
    Charset cs = Charset.forName("UTF-8");

    Map<String, File> entryMap = new HashMap<String, File>();
    Set<File> entries = new LinkedHashSet<File>();
    List<String> paths = new ArrayList<String>();

    CRC32 crc32 = new CRC32();
    /*
     * cflag: create
     * uflag: update
     * xflag: xtract
     * tflag: table
     * vflag: verbose
     * flag0: no zip compression (store only)
     */
    boolean cflag, uflag, xflag, tflag, vflag, flag0;

    private static ResourceBundle rsrc;
    static {
        try {
            // just use the jar message
            rsrc = ResourceBundle.getBundle("sun.tools.jar.resources.jar");
        } catch (MissingResourceException e) {
            throw new Error("Fatal: Resource for jar is missing");
        }
    }

    public zip(PrintStream out, PrintStream err, String program) {
        this.out = out;
        this.err = err;
        this.program = program;
    }

    private boolean ok;

    public synchronized boolean run(String args[]) {
        ok = true;
        if (!parseArgs(args)) {
            return false;
        }
        try {
            if (cflag || uflag) {
                if (fname != null) {
                    zname = fname.replace(File.separatorChar, '/');
                    if (zname.startsWith("./")) {
                        zname = zname.substring(2);
                    }
                }
            }
            if (cflag) {
                OutputStream out;
                if (fname != null) {
                    out = new FileOutputStream(fname);
                } else {
                    out = new FileOutputStream(FileDescriptor.out);
                    if (vflag) {
                         vflag = false;
                    }
                }
                expand(null, files, false);
                create(new BufferedOutputStream(out, 4096));
                out.close();
            } else if (uflag) {
                File inputFile = null, tmpFile = null;
                FileInputStream in;
                FileOutputStream out;
                if (fname != null) {
                    inputFile = new File(fname);
                    String path = inputFile.getParent();
                    tmpFile = File.createTempFile("tmp", null,
                              new File((path == null) ? "." : path));
                    in = new FileInputStream(inputFile);
                    out = new FileOutputStream(tmpFile);
                } else {
                    in = new FileInputStream(FileDescriptor.in);
                    out = new FileOutputStream(FileDescriptor.out);
                    vflag = false;
                }
                expand(null, files, true);
                boolean updateOk = update(in, new BufferedOutputStream(out));
                if (ok) {
                    ok = updateOk;
                }
                in.close();
                out.close();
                if (fname != null) {
                    inputFile.delete();
                    if (!tmpFile.renameTo(inputFile)) {
                        tmpFile.delete();
                        throw new IOException(getMsg("error.write.file"));
                    }
                    tmpFile.delete();
                }
            } else if (tflag) {
                replaceFSC(files);
                if (fname != null) {
                    list(fname, files);
                } else {
                    InputStream in = new FileInputStream(FileDescriptor.in);
                    try{
                        list(new BufferedInputStream(in), files);
                    } finally {
                        in.close();
                    }
                }
            } else if (xflag) {
                replaceFSC(files);
                if (fname != null && files != null) {
                    extract(fname, files);
                } else {
                    InputStream in = (fname == null)
                        ? new FileInputStream(FileDescriptor.in)
                        : new FileInputStream(fname);
                    try {
                        extract(new BufferedInputStream(in), files);
                    } finally {
                        in.close();
                    }
                }
            }
        } catch (IOException e) {
            fatalError(e);
            ok = false;
        } catch (Error ee) {
            ee.printStackTrace();
            ok = false;
        } catch (Throwable t) {
            t.printStackTrace();
            ok = false;
        }
        out.flush();
        err.flush();
        return ok;
    }


    boolean parseArgs(String args[]) {
        try {
            args = parse(args);
        } catch (FileNotFoundException e) {
            fatalError(formatMsg("error.cant.open", e.getMessage()));
            return false;
        } catch (IOException e) {
            fatalError(e);
            return false;
        }
        int count = 1;
        try {
            String flags = args[0];
            if (flags.startsWith("-")) {
                flags = flags.substring(1);
            }
            for (int i = 0; i < flags.length(); i++) {
                switch (flags.charAt(i)) {
                case 'c':
                    if (xflag || tflag || uflag) {
                        usageError();
                        return false;
                    }
                    cflag = true;
                    break;
                case 'u':
                    if (cflag || xflag || tflag) {
                        usageError();
                        return false;
                    }
                    uflag = true;
                    break;
                case 'x':
                    if (cflag || uflag || tflag) {
                        usageError();
                        return false;
                    }
                    xflag = true;
                    break;
                case 't':
                    if (cflag || uflag || xflag) {
                        usageError();
                        return false;
                    }
                    tflag = true;
                    break;
                case 'v':
                    vflag = true;
                    break;
                case 'f':
                    fname = args[count++];
                    break;
                case '0':
                    flag0 = true;
                    break;
                default:
                    error(formatMsg("error.illegal.option",
                                String.valueOf(flags.charAt(i))));
                    usageError();
                    return false;
                }
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            usageError();
            return false;
        }
        if (!cflag && !tflag && !xflag && !uflag) {
            error(getMsg("error.bad.option"));
            usageError();
            return false;
        }
        /* parse file arguments */
        int n = args.length - count;
        if (n > 0) {
            int k = 0;
            String[] nameBuf = new String[n];
            try {
                for (int i = count; i < args.length; i++) {
                    if (args[i].equals("-encoding")) {
                        cs = Charset.forName(args[++i]);
                    } else if (args[i].equals("-C")) {
                        /* change the directory */
                        String dir = args[++i];
                        dir = (dir.endsWith(File.separator) ?
                               dir : (dir + File.separator));
                        dir = dir.replace(File.separatorChar, '/');
                        while (dir.indexOf("//") > -1) {
                            dir = dir.replace("//", "/");
                        }
                        paths.add(dir.replace(File.separatorChar, '/'));
                        nameBuf[k++] = dir + args[++i];
                    } else {
                        nameBuf[k++] = args[i];
                    }
                }
            } catch (ArrayIndexOutOfBoundsException e) {
                e.printStackTrace();
                usageError();
                return false;
            }
            if (k != 0) {
                files = new String[k];
                System.arraycopy(nameBuf, 0, files, 0, k);
            }
        } else if (cflag || uflag) {
            error(getMsg("error.bad.uflag"));
            usageError();
            return false;
        }
        return true;
    }

    void expand(File dir, String[] files, boolean isUpdate) {
        if (files == null) {
            return;
        }
        for (int i = 0; i < files.length; i++) {
            File f;
            if (dir == null) {
                f = new File(files[i]);
            } else {
                f = new File(dir, files[i]);
            }
            if (f.isFile()) {
                if (entries.add(f)) {
                    if (isUpdate)
                        entryMap.put(entryName(f.getPath()), f);
                }
            } else if (f.isDirectory()) {
                if (entries.add(f)) {
                    if (isUpdate) {
                        String dirPath = f.getPath();
                        dirPath = (dirPath.endsWith(File.separator)) ? dirPath :
                            (dirPath + File.separator);
                        entryMap.put(entryName(dirPath), f);
                    }
                    expand(f, f.list(), isUpdate);
                }
            } else {
                error(formatMsg("error.nosuch.fileordir", String.valueOf(f)));
                ok = false;
            }
        }
    }

    void create(OutputStream out) throws IOException
    {
        try (ZipOutputStream zos = new ZipOutputStream(out, cs)) {
            if (flag0) {
                zos.setMethod(ZipOutputStream.STORED);
            }
            for (File file: entries) {
                addFile(zos, file);
            }
        }
    }

    boolean update(InputStream in, OutputStream out) throws IOException
    {
        try (ZipInputStream zis = new ZipInputStream(in, cs);
             ZipOutputStream zos = new ZipOutputStream(out, cs))
        {
            ZipEntry e = null;
            byte[] buf = new byte[1024];
            int n = 0;
            boolean updateOk = true;

            // put the old entries first, replace if necessary
            while ((e = zis.getNextEntry()) != null) {
                String name = e.getName();
                if (!entryMap.containsKey(name)) { // copy the old stuff
                    // do our own compression
                    ZipEntry e2 = new ZipEntry(name);
                    e2.setMethod(e.getMethod());
                    e2.setTime(e.getTime());
                    e2.setComment(e.getComment());
                    e2.setExtra(e.getExtra());
                    if (e.getMethod() == ZipEntry.STORED) {
                        e2.setSize(e.getSize());
                        e2.setCrc(e.getCrc());
                    }
                    zos.putNextEntry(e2);
                    while ((n = zis.read(buf, 0, buf.length)) != -1) {
                        zos.write(buf, 0, n);
                    }
                } else { // replace with the new files
                    File f = entryMap.get(name);
                    addFile(zos, f);
                    entryMap.remove(name);
                    entries.remove(f);
                }
            }

            // add the remaining new files
            for (File f: entries) {
                addFile(zos, f);
            }
        }
        return updateOk;
    }

    private String entryName(String name) {
        name = name.replace(File.separatorChar, '/');
        String matchPath = "";
        for (String path : paths) {
            if (name.startsWith(path) && (path.length() > matchPath.length())) {
                matchPath = path;
            }
        }
        name = name.substring(matchPath.length());

        if (name.startsWith("/")) {
            name = name.substring(1);
        } else if (name.startsWith("./")) {
            name = name.substring(2);
        }
        return name;
    }

    void addFile(ZipOutputStream zos, File file) throws IOException {
        String name = file.getPath();
        boolean isDir = file.isDirectory();
        if (isDir) {
            name = name.endsWith(File.separator) ? name :
                (name + File.separator);
        }
        name = entryName(name);

        if (name.equals("") || name.equals(".") || name.equals(zname)) {
            return;
        }

        long size = isDir ? 0 : file.length();

        if (vflag) {
            out.print(formatMsg("out.adding", name));
        }
        ZipEntry e = new ZipEntry(name);
        e.setTime(file.lastModified());
        if (size == 0) {
            e.setMethod(ZipEntry.STORED);
            e.setSize(0);
            e.setCrc(0);
        } else if (flag0) {
            e.setSize(size);
            e.setMethod(ZipEntry.STORED);
            crc32File(e, file);
        }
        zos.putNextEntry(e);
        if (!isDir) {
            byte[] buf = new byte[8192];
            int len;
            InputStream is = new BufferedInputStream(new FileInputStream(file));
            while ((len = is.read(buf, 0, buf.length)) != -1) {
                zos.write(buf, 0, len);
            }
            is.close();
        }
        zos.closeEntry();
        /* report how much compression occurred. */
        if (vflag) {
            size = e.getSize();
            long csize = e.getCompressedSize();
            out.print(formatMsg2("out.size", String.valueOf(size),
                        String.valueOf(csize)));
            if (e.getMethod() == ZipEntry.DEFLATED) {
                long ratio = 0;
                if (size != 0) {
                    ratio = ((size - csize) * 100) / size;
                }
                output(formatMsg("out.deflated", String.valueOf(ratio)));
            } else {
                output(getMsg("out.stored"));
            }
        }
    }

    private void crc32File(ZipEntry e, File f) throws IOException {
        InputStream is = new BufferedInputStream(new FileInputStream(f));
        byte[] buf = new byte[8192];
        crc32.reset();
        int r = 0;
        int nread = 0;
        long len = f.length();
        while ((r = is.read(buf)) != -1) {
            nread += r;
            crc32.update(buf, 0, r);
        }
        is.close();
        if (nread != (int) len) {
            throw new ZipException(formatMsg(
                        "error.incorrect.length", f.getPath()));
        }
        e.setCrc(crc32.getValue());
    }

    void replaceFSC(String files[]) {
        if (files != null) {
            for (String file : files) {
                file = file.replace(File.separatorChar, '/');
            }
        }
    }

    Set<ZipEntry> newDirSet() {
        return new HashSet<ZipEntry>() {
            public boolean add(ZipEntry e) {
                return (e == null || super.add(e));
            }};
    }

    void updateLastModifiedTime(Set<ZipEntry> zes) throws IOException {
        for (ZipEntry ze : zes) {
            long lastModified = ze.getTime();
            if (lastModified != -1) {
                File f = new File(ze.getName().replace('/', File.separatorChar));
                f.setLastModified(lastModified);
            }
        }
    }

    void extract(InputStream in, String files[]) throws IOException {
        ZipInputStream zis = new ZipInputStream(in, cs);
        ZipEntry e;
        Set<ZipEntry> dirs = newDirSet();
        while ((e = zis.getNextEntry()) != null) {
            if (files == null) {
                dirs.add(extractFile(zis, e));
            } else {
                String name = e.getName();
                for (String file : files) {
                    if (name.startsWith(file)) {
                        dirs.add(extractFile(zis, e));
                        break;
                    }
                }
            }
        }
        updateLastModifiedTime(dirs);
    }

    void extract(String fname, String files[]) throws IOException {
        try (ZipFile zf = new ZipFile(fname, cs)) {
            Set<ZipEntry> dirs = newDirSet();
            Enumeration<? extends ZipEntry> zes = zf.entries();
            while (zes.hasMoreElements()) {
                ZipEntry e = zes.nextElement();
                InputStream is;
                if (files == null) {
                    dirs.add(extractFile(zf.getInputStream(e), e));
                } else {
                    String name = e.getName();
                    for (String file : files) {
                        if (name.startsWith(file)) {
                            dirs.add(extractFile(zf.getInputStream(e), e));
                            break;
                        }
                    }
                }
            }
        }
        updateLastModifiedTime(dirs);
    }

    ZipEntry extractFile(InputStream is, ZipEntry e) throws IOException {
        ZipEntry rc = null;
        String name = e.getName();
        File f = new File(e.getName().replace('/', File.separatorChar));
        if (e.isDirectory()) {
            if (f.exists()) {
                if (!f.isDirectory()) {
                    throw new IOException(formatMsg("error.create.dir",
                        f.getPath()));
                }
            } else {
                if (!f.mkdirs()) {
                    throw new IOException(formatMsg("error.create.dir",
                        f.getPath()));
                } else {
                    rc = e;
                }
            }
            if (vflag) {
                output(formatMsg("out.create", name));
            }
        } else {
            if (f.getParent() != null) {
                File d = new File(f.getParent());
                if (!d.exists() && !d.mkdirs() || !d.isDirectory()) {
                    throw new IOException(formatMsg(
                        "error.create.dir", d.getPath()));
                }
            }
            OutputStream os = new FileOutputStream(f);
            byte[] b = new byte[8192];
            int len;
            try {
                while ((len = is.read(b, 0, b.length)) != -1) {
                    os.write(b, 0, len);
                }
            } finally {
                if (is instanceof ZipInputStream)
                    ((ZipInputStream)is).closeEntry();
                else
                    is.close();
                os.close();
            }
            if (vflag) {
                if (e.getMethod() == ZipEntry.DEFLATED) {
                    output(formatMsg("out.inflated", name));
                } else {
                    output(formatMsg("out.extracted", name));
                }
            }
        }
        long lastModified = e.getTime();
        if (lastModified != -1) {
            f.setLastModified(lastModified);
        }
        return rc;
    }

    void list(InputStream in, String files[]) throws IOException {
        ZipInputStream zis = new ZipInputStream(in, cs);
        ZipEntry e;
        while ((e = zis.getNextEntry()) != null) {
            zis.closeEntry();
            printEntry(e, files);
        }
    }

    void list(String fname, String files[]) throws IOException {
        try (ZipFile zf = new ZipFile(fname, cs)) {
            Enumeration<? extends ZipEntry> zes = zf.entries();
            while (zes.hasMoreElements()) {
                printEntry(zes.nextElement(), files);
            }
        }
    }

    void printEntry(ZipEntry e, String[] files) throws IOException {
        if (files == null) {
            printEntry(e);
        } else {
            String name = e.getName();
            for (String file : files) {
                if (name.startsWith(file)) {
                    printEntry(e);
                    return;
                }
            }
        }
    }

    void printEntry(ZipEntry e) throws IOException {
        if (vflag) {
            StringBuilder sb = new StringBuilder();
            String s = Long.toString(e.getSize());
            for (int i = 6 - s.length(); i > 0; --i) {
                sb.append(' ');
            }
            sb.append(s).append(' ').append(new Date(e.getTime()).toString());
            sb.append(' ').append(e.getName());
            output(sb.toString());
        } else {
            output(e.getName());
        }
    }

    void usageError() {
        error(
        "Usage: zip {ctxu}[vf0] [zip-file] [-encoding encname][-C dir] files ...\n" +
        "Options:\n" +
        "   -c  create new archive\n" +
        "   -t  list table of contents for archive\n" +
        "   -x  extract named (or all) files from archive\n" +
        "   -u  update existing archive\n" +
        "   -v  generate verbose output on standard output\n" +
        "   -f  specify archive file name\n" +
        "   -0  store only; use no ZIP compression\n" +
        "   -C  change to the specified directory and include the following file\n" +
        "If any file is a directory then it is processed recursively.\n");
    }

    void fatalError(Exception e) {
        e.printStackTrace();
    }


    void fatalError(String s) {
        error(program + ": " + s);
    }


    protected void output(String s) {
        out.println(s);
    }

    protected void error(String s) {
        err.println(s);
    }

    private String getMsg(String key) {
        try {
            return (rsrc.getString(key));
        } catch (MissingResourceException e) {
            throw new Error("Error in message file");
        }
    }

    private String formatMsg(String key, String arg) {
        String msg = getMsg(key);
        String[] args = new String[1];
        args[0] = arg;
        return MessageFormat.format(msg, (Object[]) args);
    }

    private String formatMsg2(String key, String arg, String arg1) {
        String msg = getMsg(key);
        String[] args = new String[2];
        args[0] = arg;
        args[1] = arg1;
        return MessageFormat.format(msg, (Object[]) args);
    }

    public static String[] parse(String[] args) throws IOException
    {
        ArrayList<String> newArgs = new ArrayList<String>(args.length);
        for (int i = 0; i < args.length; i++) {
            String arg = args[i];
            if (arg.length() > 1 && arg.charAt(0) == '@') {
                arg = arg.substring(1);
                if (arg.charAt(0) == '@') {
                    newArgs.add(arg);
                } else {
                    loadCmdFile(arg, newArgs);
                }
            } else {
                newArgs.add(arg);
            }
        }
        return newArgs.toArray(new String[newArgs.size()]);
    }

    private static void loadCmdFile(String name, List<String> args) throws IOException
    {
        Reader r = new BufferedReader(new FileReader(name));
        StreamTokenizer st = new StreamTokenizer(r);
        st.resetSyntax();
        st.wordChars(' ', 255);
        st.whitespaceChars(0, ' ');
        st.commentChar('#');
        st.quoteChar('"');
        st.quoteChar('\'');
        while (st.nextToken() != st.TT_EOF) {
            args.add(st.sval);
        }
        r.close();
    }

    public static void main(String args[]) {
        zip z = new zip(System.out, System.err, "zip");
        System.exit(z.run(args) ? 0 : 1);
    }
}

