/*
 * Copyright (c) 2013, 2024, 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.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.classfile.ClassTransform;
import java.lang.classfile.ClassFile;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

// Compile with -XDignore.symbol.file=true

public class BogoLoader extends ClassLoader {

    /**
     * Use this property to verify that the desired classloading is happening.
     */
    private final boolean verbose = Boolean.getBoolean("bogoloader.verbose");
    /**
     * Use this property to disable replacement for testing purposes.
     */
    private final boolean noReplace = Boolean.getBoolean("bogoloader.noreplace");

    /**
     * Set of class names that should be loaded with this loader.
     * Others are loaded with the system class loader, except for those
     * that are transformed.
     */
    private Set<String> nonSystem;

    /**
     * Map from class names to a bytecode transformer factory.
     */
    private Map<String, ClassTransform> replaced;

    /**
     * Keep track (not terribly efficiently) of which classes have already
     * been loaded by this class loader.
     */
    private final Vector<String> history = new Vector<String>();

    private boolean useSystemLoader(String name) {
        return ! nonSystem.contains(name) && ! replaced.containsKey(name);
    }

    public BogoLoader(Set<String> non_system, Map<String, ClassTransform> replaced) {
        super(Thread.currentThread().getContextClassLoader());
        this.nonSystem = non_system;
        this.replaced = replaced;
    }

    private byte[] readResource(String className) throws IOException {
        return readResource(className, "class");
    }

    private byte[] readResource(String className, String suffix) throws IOException {
        // Note to the unwary -- "/" works on Windows, leave it alone.
        String fileName = className.replace('.', '/') + "." + suffix;
        InputStream origStream = getResourceAsStream(fileName);
        if (origStream == null) {
            throw new IOException("Resource not found : " + fileName);
        }
        BufferedInputStream stream = new java.io.BufferedInputStream(origStream);
        byte[] data = new byte[stream.available()];
        int how_many = stream.read(data);
        // Really ought to deal with the corner cases of stream.available()
        return data;
    }

    protected byte[] getClass(String name) throws ClassNotFoundException,
    IOException {
        return readResource(name, "class");
    }

    /**
     * Loads the named class from the system class loader unless
     * the name appears in either replaced or nonSystem.
     * nonSystem classes are loaded into this classloader,
     * and replaced classes get their content from the specified array
     * of bytes (and are also loaded into this classloader).
     */
    protected Class<?> loadClass(String name, boolean resolve)
            throws ClassNotFoundException {
        Class<?> clazz;

        if (history.contains(name)) {
            Class<?> c = this.findLoadedClass(name);
            return c;
        }
        if (useSystemLoader(name)) {
            clazz = findSystemClass(name);
            if (verbose) System.err.println("Loading system class " + name);
        } else {
            history.add(name);
            try {
                if (verbose) {
                    System.err.println("Loading classloader class " + name);
                }
                byte[] classData = getClass(name);
                boolean expanded = false;
                if (!noReplace && replaced.containsKey(name)) {
                    if (verbose) {
                        System.err.println("Replacing class " + name);
                    }
                    var cf = ClassFile.of();
                    classData = cf.transformClass(cf.parse(classData), replaced.get(name));
                }
                clazz = defineClass(name, classData, 0, classData.length);
            } catch (java.io.EOFException ioe) {
                throw new ClassNotFoundException(
                        "IO Exception in reading class : " + name + " ", ioe);
            } catch (ClassFormatError ioe) {
                throw new ClassNotFoundException(
                        "ClassFormatError in reading class file: ", ioe);
            } catch (IOException ioe) {
                throw new ClassNotFoundException(
                        "IO Exception in reading class file: ", ioe);
            }
        }
        if (clazz == null) {
            throw new ClassNotFoundException(name);
        }
        if (resolve) {
            resolveClass(clazz);
        }
        return clazz;
    }
}
