/*
 * Copyright (c) 2015, 2016, 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.
 *
 * 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.
 */

/*
 * @test
 * @bug 8132734 8144062 8159785
 * @summary Test that URL connections to multi-release jars can be runtime versioned
 * @library /lib/testlibrary/java/util/jar
 * @modules java.compiler
 *          jdk.httpserver
 *          jdk.jartool
 * @build Compiler JarBuilder CreateMultiReleaseTestJars SimpleHttpServer
 * @run testng MultiReleaseJarURLConnection
 */

import java.io.IOException;
import java.io.InputStream;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.jar.JarFile;

import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class MultiReleaseJarURLConnection {
    String userdir = System.getProperty("user.dir",".");
    String unversioned = userdir + "/unversioned.jar";
    String unsigned = userdir + "/multi-release.jar";
    String signed = userdir + "/signed-multi-release.jar";
    SimpleHttpServer server;

    @BeforeClass
    public void initialize() throws Exception {
        CreateMultiReleaseTestJars creator = new CreateMultiReleaseTestJars();
        creator.compileEntries();
        creator.buildUnversionedJar();
        creator.buildMultiReleaseJar();
        creator.buildSignedMultiReleaseJar();

        server = new SimpleHttpServer();
        server.start();

    }

    @AfterClass
    public void close() throws IOException {
        // Windows requires server to stop before file is deleted
        if (server != null)
            server.stop();
        Files.delete(Paths.get(unversioned));
        Files.delete(Paths.get(unsigned));
        Files.delete(Paths.get(signed));
    }

    @DataProvider(name = "data")
    public Object[][] createData() {
        return new Object[][]{
                {"unversioned", unversioned},
                {"unsigned", unsigned},
                {"signed", signed}
        };
    }

    @Test(dataProvider = "data")
    public void testRuntimeVersioning(String style, String file) throws Exception {
        String urlFile = "jar:file:" + file + "!/";
        String baseUrlEntry = urlFile + "version/Version.java";
        String rtreturn = "return " + Runtime.version().major();

        Assert.assertTrue(readAndCompare(new URL(baseUrlEntry), "return 8"));
        // #runtime is "magic" for a multi-release jar, but not for unversioned jar
        Assert.assertTrue(readAndCompare(new URL(baseUrlEntry + "#runtime"),
                style.equals("unversioned") ? "return 8" : rtreturn));
        // #fragment or any other fragment is not magic
        Assert.assertTrue(readAndCompare(new URL(baseUrlEntry + "#fragment"), "return 8"));
        // cached entities not affected
        Assert.assertTrue(readAndCompare(new URL(baseUrlEntry), "return 8"));

        // the following tests will not work with unversioned jars
        if (style.equals("unversioned")) return;

        // direct access to versioned entry
        String versUrlEntry = urlFile + "META-INF/versions/" + Runtime.version().major()
                + "/version/Version.java";
        Assert.assertTrue(readAndCompare(new URL(versUrlEntry), rtreturn));
        // adding any fragment does not change things
        Assert.assertTrue(readAndCompare(new URL(versUrlEntry + "#runtime"), rtreturn));
        Assert.assertTrue(readAndCompare(new URL(versUrlEntry + "#fragment"), rtreturn));

        // it really doesn't change things
        versUrlEntry = urlFile + "META-INF/versions/10/version/Version.java";
        Assert.assertTrue(readAndCompare(new URL(versUrlEntry), "return 10"));
        Assert.assertTrue(readAndCompare(new URL(versUrlEntry + "#runtime"), "return 10"));
        Assert.assertTrue(readAndCompare(new URL(versUrlEntry + "#fragment"), "return 10"));
    }

    @Test(dataProvider = "data")
    public void testCachedJars(String style, String file) throws Exception {
        String urlFile = "jar:file:" + file + "!/";

        URL rootUrl = new URL(urlFile);
        JarURLConnection juc = (JarURLConnection)rootUrl.openConnection();
        JarFile rootJar = juc.getJarFile();
        JarFile.Release root = rootJar.getVersion();

        URL runtimeUrl = new URL(urlFile + "#runtime");
        juc = (JarURLConnection)runtimeUrl.openConnection();
        JarFile runtimeJar = juc.getJarFile();
        JarFile.Release runtime = runtimeJar.getVersion();
        if (style.equals("unversioned")) {
            Assert.assertEquals(root, runtime);
        } else {
            Assert.assertNotEquals(root, runtime);
        }

        juc = (JarURLConnection)rootUrl.openConnection();
        JarFile jar = juc.getJarFile();
        Assert.assertEquals(jar.getVersion(), root);
        Assert.assertEquals(jar, rootJar);

        juc = (JarURLConnection)runtimeUrl.openConnection();
        jar = juc.getJarFile();
        Assert.assertEquals(jar.getVersion(), runtime);
        Assert.assertEquals(jar, runtimeJar);

        rootJar.close();
        runtimeJar.close();
        jar.close(); // probably not needed
    }

    @DataProvider(name = "resourcedata")
    public Object[][] createResourceData() throws Exception {
        return new Object[][]{
                {"unversioned", Paths.get(unversioned).toUri().toURL()},
                {"unsigned", Paths.get(unsigned).toUri().toURL()},
                {"signed", Paths.get(signed).toUri().toURL()},
                {"unversioned", new URL("file:" + unversioned)},
                {"unsigned", new URL("file:" + unsigned)},
                {"signed", new URL("file:" + signed)},
                {"unversioned", new URL("jar:file:" + unversioned + "!/")},
                {"unsigned", new URL("jar:file:" + unsigned + "!/")},
                {"signed", new URL("jar:file:" + signed + "!/")},
                // external jar received via http protocol
                {"http", new URL("jar:http://localhost:" + server.getPort() + "/multi-release.jar!/")},
                {"http", new URL("http://localhost:" + server.getPort() + "/multi-release.jar")},

        };
    }

    @Test(dataProvider = "resourcedata")
    public void testResources(String style, URL url) throws Throwable {
        //System.out.println("  testing " + style + " url: " + url);
        URL[] urls = {url};
        URLClassLoader cldr = new URLClassLoader(urls);
        Class<?> vcls = cldr.loadClass("version.Version");

        // verify we are loading a runtime versioned class
        MethodType mt = MethodType.methodType(int.class);
        MethodHandle mh = MethodHandles.lookup().findVirtual(vcls, "getVersion", mt);
        Assert.assertEquals((int)mh.invoke(vcls.newInstance()),
                style.equals("unversioned") ? 8 : Runtime.version().major());

        // now get a resource and verify that we don't have a fragment attached
        Enumeration<URL> vclsUrlEnum = cldr.getResources("version/Version.class");
        Assert.assertTrue(vclsUrlEnum.hasMoreElements());
        URL vclsUrls[] = new URL[] {
            vcls.getResource("/version/Version.class"),
            vcls.getResource("Version.class"),
            cldr.getResource("version/Version.class"),
            vclsUrlEnum.nextElement()
        };
        Assert.assertFalse(vclsUrlEnum.hasMoreElements());
        for (URL vclsUrl : vclsUrls) {
            String fragment = vclsUrl.getRef();
            Assert.assertNull(fragment);

            // and verify that the the url is a reified pointer to the runtime entry
            String rep = vclsUrl.toString();
            //System.out.println("    getResource(\"/version/Version.class\") returned: " + rep);
            if (style.equals("http")) {
                Assert.assertTrue(rep.startsWith("jar:http:"));
            } else {
                Assert.assertTrue(rep.startsWith("jar:file:"));
            }
            String suffix;
            if (style.equals("unversioned")) {
                suffix = ".jar!/version/Version.class";
            } else {
                suffix = ".jar!/META-INF/versions/" + Runtime.version().major()
                        + "/version/Version.class";
            }
            Assert.assertTrue(rep.endsWith(suffix));
        }
        cldr.close();
    }


    private boolean readAndCompare(URL url, String match) throws Exception {
        boolean result;
        // necessary to do it this way, instead of openStream(), so we can
        // close underlying JarFile, otherwise windows can't delete the file
        URLConnection conn = url.openConnection();
        try (InputStream is = conn.getInputStream()) {
            byte[] bytes = is.readAllBytes();
            result = (new String(bytes)).contains(match);
        }
        if (conn instanceof JarURLConnection) {
            ((JarURLConnection)conn).getJarFile().close();
        }
        return result;
    }
}
