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

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Dump a class file for a class on the class path in the current directory, or
 * in the specified JAR file. This class is usually used when you build a class
 * from a test library, but want to use this class in a sub-process.
 *
 * For example, to build the following library class:
 * test/lib/sun/hotspot/WhiteBox.java
 *
 * You would use the following tags:
 *
 * @library /test/lib
 * @build sun.hotspot.WhiteBox
 *
 * JTREG would build the class file under
 * ${JTWork}/classes/test/lib/sun/hotspot/WhiteBox.class
 *
 * With you run your main test class using "@run main MyMainClass", JTREG would setup the
 * -classpath to include "${JTWork}/classes/test/lib/", so MyMainClass would be able to
 * load the WhiteBox class.
 *
 * However, if you run a sub process, and do not wish to use the exact same -classpath,
 * You can use ClassFileInstaller to ensure that WhiteBox is available in the current
 * directory of your test:
 *
 * @run driver ClassFileInstaller sun.hotspot.WhiteBox
 *
 * Or, you can use the -jar option to store the class in the specified JAR file. If a relative
 * path name is given, the JAR file would be relative to the current directory of
 *
 * @run driver ClassFileInstaller -jar myjar.jar sun.hotspot.WhiteBox
 */
public class ClassFileInstaller {
    /**
     * You can enable debug tracing of ClassFileInstaller by running JTREG with
     * jtreg -DClassFileInstaller.debug=true ... <names of tests>
     */
    public static boolean DEBUG = Boolean.getBoolean("ClassFileInstaller.debug");

    /**
     * @param args The names of the classes to dump
     * @throws Exception
     */
    public static void main(String... args) throws Exception {
        if (args.length > 1 && args[0].equals("-jar")) {
            if (args.length < 2) {
                throw new RuntimeException("Usage: ClassFileInstaller <options> <classes>\n" +
                                           "where possible options include:\n" +
                                           "  -jar <path>             Write to the JAR file <path>");
            }
            String jarFile = args[1];
            String[] classes = addInnerClasses(args, 2);
            writeJar_impl(jarFile, null, classes);
        } else {
            if (DEBUG) {
                System.out.println("ClassFileInstaller: Writing to " + System.getProperty("user.dir"));
            }
            String[] classes = addInnerClasses(args, 0);
            for (String cls : classes) {
                writeClassToDisk(cls);
            }
        }
    }

    // Add commonly used inner classes that are often omitted by mistake. Currently
    // we support only sun.hotspot.WhiteBox$WhiteBoxPermission. See JDK-8199290
    private static String[] addInnerClasses(String[] classes, int startIdx) {
        boolean seenWB = false;
        boolean seenWBInner = false;
        final String wb = "sun.hotspot.WhiteBox";
        final String wbInner = "sun.hotspot.WhiteBox$WhiteBoxPermission";

        ArrayList<String> list = new ArrayList<>();

        for (int i = startIdx; i < classes.length; i++) {
            String cls = classes[i];
            list.add(cls);
            switch (cls) {
            case wb:      seenWB      = true; break;
            case wbInner: seenWBInner = true; break;
            }
        }
        if (seenWB && !seenWBInner) {
            list.add(wbInner);
        }

        String[] array = new String[list.size()];
        list.toArray(array);
        return array;
    }

    public static class Manifest {
        private InputStream in;

        private Manifest(InputStream in) {
            this.in = in;
        }

        static Manifest fromSourceFile(String fileName) throws Exception {
            String pathName = System.getProperty("test.src") + File.separator + fileName;
            return new Manifest(new FileInputStream(pathName));
        }

        // Example:
        //  String manifest = "Premain-Class: RedefineClassHelper\n" +
        //                "Can-Redefine-Classes: true\n";
        //  ClassFileInstaller.writeJar("redefineagent.jar",
        //    ClassFileInstaller.Manifest.fromString(manifest),
        //    "RedefineClassHelper");
        static Manifest fromString(String manifest) throws Exception {
            return new Manifest(new ByteArrayInputStream(manifest.getBytes()));
        }

        public InputStream getInputStream() {
            return in;
        }
    }

    private static void writeJar_impl(String jarFile, Manifest manifest, String classes[]) throws Exception {
        if (DEBUG) {
            System.out.println("ClassFileInstaller: Writing to " + getJarPath(jarFile));
        }

        (new File(jarFile)).delete();
        FileOutputStream fos = new FileOutputStream(jarFile);
        ZipOutputStream zos = new ZipOutputStream(fos);

        // The manifest must be the first or second entry. See comments in JarInputStream
        // constructor and JDK-5046178.
        if (manifest != null) {
            writeToDisk(zos, "META-INF/MANIFEST.MF", manifest.getInputStream());
        }

        for (String cls : classes) {
            writeClassToDisk(zos, cls);
        }

        zos.close();
        fos.close();
    }

    /*
     * You can call ClassFileInstaller.writeJar() from your main test class instead of
     * using "@run ClassFileInstaller -jar ...". E.g.,
     *
     * String jarPath = ClassFileInstaller.getJarPath("myjar.jar", "sun.hotspot.WhiteBox")
     *
     * If you call this API, make sure you build ClassFileInstaller with the following tags:
     *
     * @library testlibrary
     * @build ClassFileInstaller
     */
    public static String writeJar(String jarFile, String... classes) throws Exception {
        classes = addInnerClasses(classes, 0);
        writeJar_impl(jarFile, null, classes);
        return getJarPath(jarFile);
    }

    public static String writeJar(String jarFile, Manifest manifest, String... classes) throws Exception {
        classes = addInnerClasses(classes, 0);
        writeJar_impl(jarFile, manifest, classes);
        return getJarPath(jarFile);
    }

    /**
     * This returns the absolute path to the file specified in "@ClassFileInstaller -jar myjar.jar",
     * In your test program, instead of using the JAR file name directly:
     *
     * String jarPath = "myjar.jar";
     *
     * you should call this function, like:
     *
     * String jarPath = ClassFileInstaller.getJarPath("myjar.jar")
     *
     * The reasons are:
     * (1) Using absolute path makes it easy to cut-and-paste from the JTR file and rerun your
     *     test in any directory.
     * (2) In the future, we may make the JAR file name unique to avoid clobbering
     *     during parallel JTREG execution.
     *
     */
    public static String getJarPath(String jarFileName) {
        return new File(jarFileName).getAbsolutePath();
    }

    public static void writeClassToDisk(String className) throws Exception {
        writeClassToDisk((ZipOutputStream)null, className);
    }
    private static void writeClassToDisk(ZipOutputStream zos, String className) throws Exception {
        writeClassToDisk(zos, className, "");
    }

    public static void writeClassToDisk(String className, String prependPath) throws Exception {
        writeClassToDisk(null, className, prependPath);
    }
    private static void writeClassToDisk(ZipOutputStream zos, String className, String prependPath) throws Exception {
        ClassLoader cl = ClassFileInstaller.class.getClassLoader();

        // Convert dotted class name to a path to a class file
        String pathName = className.replace('.', '/').concat(".class");
        InputStream is = cl.getResourceAsStream(pathName);
        if (is == null) {
            throw new RuntimeException("Failed to find " + pathName);
        }
        if (prependPath.length() > 0) {
            pathName = prependPath + "/" + pathName;
        }
        writeToDisk(zos, pathName, is);
    }

    public static void writeClassToDisk(String className, byte[] bytecode) throws Exception {
        writeClassToDisk(null, className, bytecode);
    }
    private static void writeClassToDisk(ZipOutputStream zos, String className, byte[] bytecode) throws Exception {
        writeClassToDisk(zos, className, bytecode, "");
    }

    public static void writeClassToDisk(String className, byte[] bytecode, String prependPath) throws Exception {
        writeClassToDisk(null, className, bytecode, prependPath);
    }
    private static void writeClassToDisk(ZipOutputStream zos, String className, byte[] bytecode, String prependPath) throws Exception {
        // Convert dotted class name to a path to a class file
        String pathName = className.replace('.', '/').concat(".class");
        if (prependPath.length() > 0) {
            pathName = prependPath + "/" + pathName;
        }
        writeToDisk(zos, pathName, new ByteArrayInputStream(bytecode));
    }

    private static void writeToDisk(ZipOutputStream zos, String pathName, InputStream is) throws Exception {
        if (DEBUG) {
            System.out.println("ClassFileInstaller: Writing " + pathName);
        }
        if (zos != null) {
            ZipEntry ze = new ZipEntry(pathName);
            zos.putNextEntry(ze);
            byte[] buf = new byte[1024];
            int len;
            while ((len = is.read(buf))>0){
                zos.write(buf, 0, len);
            }
        } else {
            // Create the class file's package directory
            Path p = Paths.get(pathName);
            if (pathName.contains("/")) {
                Files.createDirectories(p.getParent());
            }
            // Create the class file
            Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING);
        }
        is.close();
    }
}
