/*
 * Copyright 2006 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 6374379
 * @summary Verify that we can read zip file names > 255 chars long
 */

import java.io.*;
import java.util.jar.*;
import java.util.zip.*;
import java.util.Stack;

public class ReadLongZipFileName {
    private static String entryName = "testFile.txt";;

    public static void realMain(String args[]) {
        String longDirName = "abcdefghijklmnopqrstuvwx"; // 24 chars.
        String jarFileName = "areallylargejarfilename.jar";    // 27 chars.
        File file = null;
        File myJarFile = null;
        int currentFileLength = 0;
        int minRequiredLength = 600; // long enough to definitely fail.
        Stack<File> directories = new Stack<File>();

        String filename = "." + File.separator;
        try {
            // Create a directory structure long enough that the filename will
            // put us over the minRequiredLength.
            do {
                filename = filename + longDirName + File.separator;
                file = new File(filename);
                file.mkdir();
                currentFileLength = file.getCanonicalPath().length();
                directories.push(file);
            } while (currentFileLength < (minRequiredLength - jarFileName.length()));

            // Create a new Jar file: use jar instead of zip to make sure long
            // names work for both zip and jar subclass.
            filename = filename + jarFileName;
            JarOutputStream out = new JarOutputStream(
                new BufferedOutputStream(
                    new FileOutputStream(filename.toString())));
            out.putNextEntry(new JarEntry(entryName));
            out.write(1);
            out.close();
            myJarFile = new File(filename.toString());
            currentFileLength = myJarFile.getCanonicalPath().length();
            if (!myJarFile.exists()) {
                fail("Jar file does not exist.");
            }
        } catch (IOException e) {
            unexpected(e, "Problem creating the Jar file.");
        }

        try {
            JarFile readJarFile = new JarFile(myJarFile);
            JarEntry je = readJarFile.getJarEntry(entryName);
            check(je != null);
            DataInputStream dis = new DataInputStream(
                readJarFile.getInputStream(je));
            byte val = dis.readByte();
            check(val == 1);
            try {
                dis.readByte();
                fail("Read past expected EOF");
            } catch (IOException e) {
                pass();
            }
            readJarFile.close();
            pass("Opened Jar file for reading with a name " + currentFileLength
                 + " characters long");
        } catch (IOException e) {
            unexpected(e, "Test failed - problem reading the Jar file back in.");
        }

        if (myJarFile != null) {
            check(myJarFile.delete());
        }

        while (! directories.empty()) {
            File f = directories.pop();
            check(f.delete());
        }
    }

    //--------------------- Infrastructure ---------------------------
    static volatile int passed = 0, failed = 0;
    static void pass() {passed++;}
    static void pass(String msg) {System.out.println(msg); passed++;}
    static void fail() {failed++; Thread.dumpStack();}
    static void fail(String msg) {System.out.println(msg); fail();}
    static void unexpected(Throwable t) {failed++; t.printStackTrace();}
    static void unexpected(Throwable t, String msg) {
        System.out.println(msg); failed++; t.printStackTrace();}
    static void check(boolean cond) {if (cond) pass(); else fail();}
    static void equal(Object x, Object y) {
        if (x == null ? y == null : x.equals(y)) pass();
        else fail(x + " not equal to " + y);}
    public static void main(String[] args) throws Throwable {
        try {realMain(args);} catch (Throwable t) {unexpected(t);}
        System.out.println("\nPassed = " + passed + " failed = " + failed);
        if (failed > 0) throw new AssertionError("Some tests failed");}
}
