/*
 * 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 6434207 6442687
 * @summary Ensure that jar ufm actually updates the
 * existing jar file's manifest with contents of the
 * manifest file.
 */

import java.io.*;
import java.util.logging.*;
import java.util.zip.*;
import sun.tools.jar.Main;

public class UpdateManifest {
    static PrintStream out = System.out;
    static PrintStream err = System.err;
    static boolean debug = true;

    public static void realMain(String[] args) throws Throwable {
        if (args.length == 0) {
            debug = false;
            File tmp = File.createTempFile("system-out-err", ".txt");
            tmp.deleteOnExit();
            out = new PrintStream(new FileOutputStream(tmp));
            err = out;
            // Attributes.read() can log a message we don't care to see.
            Logger.getLogger("java.util.jar").setLevel(Level.OFF);
        }

        try { testManifestExistence(); } catch (Throwable t) { unexpected(t); }
        try { testManifestContents(); } catch (Throwable t) { unexpected(t); }
    }

    static void testManifestExistence() throws Throwable {
        // Create a file to put in a jar file
        File existence = createTextFile("existence");

        // Create a jar file, specifying a Main-Class
        final String jarFileName = "um-existence.jar";
        new File(jarFileName).delete(); // remove pre-existing first!
        Main jartool = new Main(out, err, "jar");
        boolean status = jartool.run(
            new String[] { "cfe", jarFileName, "Hello", existence.getPath() });
        check(status);
        checkManifest(jarFileName, "Hello");

        // Update that jar file by changing the Main-Class
        jartool = new Main(out, err, "jar");
        status = jartool.run(
            new String[] { "ufe", jarFileName, "Bye" });
        check(status);
        checkManifest(jarFileName, "Bye");
    }

    static void testManifestContents() throws Throwable {
        // Create some strings we expect to find in the updated manifest
        final String animal =
            "Name: animal/marsupial";
        final String specTitle =
            "Specification-Title: Wombat";

        // Create a text file with manifest entries
        File manifestOrig = File.createTempFile("manifestOrig", ".txt");
        if (!debug) manifestOrig.deleteOnExit();
        PrintWriter pw = new PrintWriter(manifestOrig);
        pw.println("Manifest-Version: 1.0");
        pw.println("Created-By: 1.6.0-internal (Sun Microsystems Inc.)");
        pw.println("");
        pw.println(animal);
        pw.println(specTitle);
        pw.close();

        File hello = createTextFile("hello");

        // Create a jar file
        final String jarFileName = "um-test.jar";
        new File(jarFileName).delete(); // remove pre-existing first!
        Main jartool = new Main(out, err, "jar");
        boolean status = jartool.run(
                                new String[] {"cfm", jarFileName,
                                    manifestOrig.getPath(), hello.getPath() });
        check(status);

        // Create a new manifest, to use in updating the jar file.
        File manifestUpdate = File.createTempFile("manifestUpdate", ".txt");
        if (!debug) manifestUpdate.deleteOnExit();
        pw = new PrintWriter(manifestUpdate);
        final String createdBy =
            "Created-By: 1.5.0-special (Sun Microsystems Inc.)";
        final String specVersion =
            "Specification-Version: 1.0.0.0";
        pw.println(createdBy); // replaces line in the original
        pw.println("");
        pw.println(animal);
        pw.println(specVersion); // addition to animal/marsupial section
        pw.close();

        // Update jar file with manifest
        jartool = new Main(out, err, "jar");
        status = jartool.run(
            new String[] { "ufm", jarFileName, manifestUpdate.getPath() });
        check(status);

        // Extract jar, and verify contents of manifest file
        File f = new File(jarFileName);
        if (!debug) f.deleteOnExit();
        ZipFile zf = new ZipFile(f);
        ZipEntry ze = zf.getEntry("META-INF/MANIFEST.MF");
        BufferedReader r = new BufferedReader(
            new InputStreamReader(zf.getInputStream(ze)));
        r.readLine(); // skip Manifest-Version
        check(r.readLine().equals(createdBy));
        r.readLine(); // skip blank line
        check(r.readLine().equals(animal));
        String s = r.readLine();
        if (s.equals(specVersion)) {
            check(r.readLine().equals(specTitle));
        } else if (s.equals(specTitle)) {
            check(r.readLine().equals(specVersion));
        } else {
            fail("did not match specVersion nor specTitle");
        }
    }

    // --------------------- Convenience ---------------------------

    static File createTextFile(String name) throws Throwable {
        // Create a text file to put in a jar file
        File rc = File.createTempFile(name, ".txt");
        if (!debug) rc.deleteOnExit();
        PrintWriter pw = new PrintWriter(rc);
        pw.println("hello, world");
        pw.close();
        return rc;
    }

    static void checkManifest(String jarFileName, String mainClass)
                throws Throwable {
        File f = new File(jarFileName);
        if (!debug) f.deleteOnExit();
        ZipFile zf = new ZipFile(f);
        ZipEntry ze = zf.getEntry("META-INF/MANIFEST.MF");
        BufferedReader r = new BufferedReader(
            new InputStreamReader(zf.getInputStream(ze)));
        String line = r.readLine();
        while (line != null && !(line.startsWith("Main-Class:"))) {
            line = r.readLine();
        }
        if (line == null) {
            fail("Didn't find Main-Class in manifest");
        } else {
            check(line.equals("Main-Class: " + mainClass));
        }
        zf.close();
    }

    // --------------------- Infrastructure ---------------------------

    static volatile int passed = 0, failed = 0;

    static void pass() {
        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 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");
    }
}
