/*
 * Copyright 2003 Sun Microsystems, Inc.  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.
 *
 * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/* @test
   @bug 4334846
   @summary Make sure zip file comments of various sizes can be written.
   @author Martin Buchholz
 */

import java.io.*;

import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

public class Comment {
    private static final String entryName = "entryName";
    private static final String entryContents = "entryContents";
    private static final int commentMaxLength = 0xFFFF;
    private static final int [] commentLengths
        = { 0, 1, 32768, commentMaxLength - 1, commentMaxLength };

    public static void main(String argv[])
        throws Exception
    {
        for (int i = 0; i < commentLengths.length; ++i) {
            int commentLength = commentLengths[i];
            String comment = buildComment(commentLength);
            String name = "Test" + commentLength + ".zip";
            writeZipFile(name, comment);
            verifyZipFile(name, comment);
            new File(name).delete();
            System.out.println(commentLength + ": successful");
        }
    }

    private static void writeZipFile(String name, String comment)
        throws IOException
    {
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(name));
        zos.setComment(comment);
        ZipEntry ze = new ZipEntry(entryName);
        ze.setMethod(ZipEntry.DEFLATED);
        zos.putNextEntry(ze);
        new DataOutputStream(zos).writeUTF(entryContents);
        zos.closeEntry();
        zos.close();
    }

    private static void verifyZipFile(String name, String comment)
        throws Exception
    {
        // Check that Zip entry was correctly written.
        ZipFile zipFile = new ZipFile(name);
        ZipEntry zipEntry = zipFile.getEntry(entryName);
        InputStream is = zipFile.getInputStream(zipEntry);
        String result = new DataInputStream(is).readUTF();
        if (!result.equals(entryContents))
            throw new Exception("Entry contents corrupted");

        // Check that comment length was correctly written.
        RandomAccessFile file = new RandomAccessFile(name, "r");
        file.seek(file.length() - comment.length()
                  - ZipFile.ENDHDR + ZipFile.ENDCOM);
        int b1 = file.readUnsignedByte();
        int b2 = file.readUnsignedByte();
        if (b1 + (b2 << 8) != comment.length())
            throw new Exception("Zip file comment length corrupted");

        // Check that comment was correctly written.
        file.seek(file.length() - comment.length());
        byte [] bytes = new byte [comment.length()];
        file.readFully(bytes);
        if (! comment.equals(new String(bytes, "UTF8")))
            throw new Exception("Zip file comment corrupted");
    }

    private static String buildComment(int length) {
        StringBuffer result = new StringBuffer();
        while (result.length() < length) {
            /* Endhdr is 22 bytes long, so this pattern makes it easy
             * to see if it is copied correctly */
            result.append("abcdefghijklmnopqrstuvABCDEFGHIJKLMNOPQRSTUV");
        }
        String string = result.toString();
        string = string.substring(string.length() - length);
        return string;
    }
}
