/*
 * Copyright (c) 2010, 2013, 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * 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.
 */

package jdk.nashorn.internal.runtime;

import java.io.File;
import java.io.InputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.lang.reflect.Module;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.PrivilegedAction;
import java.security.Permissions;
import java.security.SecureClassLoader;

/**
 * Superclass for Nashorn class loader classes.
 */
abstract class NashornLoader extends SecureClassLoader {
    protected static final String OBJECTS_PKG        = "jdk.nashorn.internal.objects";
    protected static final String RUNTIME_PKG        = "jdk.nashorn.internal.runtime";
    protected static final String RUNTIME_ARRAYS_PKG = "jdk.nashorn.internal.runtime.arrays";
    protected static final String RUNTIME_LINKER_PKG = "jdk.nashorn.internal.runtime.linker";
    protected static final String SCRIPTS_PKG        = "jdk.nashorn.internal.scripts";
    protected static final String OBJECTS_PKG_INTERNAL        = "jdk/nashorn/internal/objects";
    protected static final String RUNTIME_PKG_INTERNAL        = "jdk/nashorn/internal/runtime";
    protected static final String RUNTIME_ARRAYS_PKG_INTERNAL = "jdk/nashorn/internal/runtime/arrays";
    protected static final String RUNTIME_LINKER_PKG_INTERNAL = "jdk/nashorn/internal/runtime/linker";
    protected static final String SCRIPTS_PKG_INTERNAL        = "jdk/nashorn/internal/scripts";

    static final Module NASHORN_MODULE = Context.class.getModule();

    private static final Permission[] SCRIPT_PERMISSIONS;

    private static final String MODULE_MANIPULATOR_NAME = SCRIPTS_PKG + ".ModuleGraphManipulator";
    private static final byte[] MODULE_MANIPULATOR_BYTES = readModuleManipulatorBytes();

    static {
        /*
         * Generated classes get access to runtime, runtime.linker, objects, scripts packages.
         * Note that the actual scripts can not access these because Java.type, Packages
         * prevent these restricted packages. And Java reflection and JSR292 access is prevented
         * for scripts. In other words, nashorn generated portions of script classes can access
         * classes in these implementation packages.
         */
        SCRIPT_PERMISSIONS = new Permission[] {
                new RuntimePermission("accessClassInPackage." + RUNTIME_PKG),
                new RuntimePermission("accessClassInPackage." + RUNTIME_LINKER_PKG),
                new RuntimePermission("accessClassInPackage." + OBJECTS_PKG),
                new RuntimePermission("accessClassInPackage." + SCRIPTS_PKG),
                new RuntimePermission("accessClassInPackage." + RUNTIME_ARRAYS_PKG)
        };
    }

    // addExport Method object on ModuleGraphManipulator
    // class loaded by this loader
    private Method addModuleExport;

    NashornLoader(final ClassLoader parent) {
        super(parent);
    }

    void loadModuleManipulator() {
        final Class<?> clazz = defineClass(MODULE_MANIPULATOR_NAME,
                MODULE_MANIPULATOR_BYTES, 0, MODULE_MANIPULATOR_BYTES.length);
        // force class initialization so that <clinit> runs!
        try {
            Class.forName(MODULE_MANIPULATOR_NAME, true, this);
        } catch (final Exception ex) {
            throw new RuntimeException(ex);
        }
        final PrivilegedAction<Void> pa = () -> {
            try {
                addModuleExport = clazz.getDeclaredMethod("addExport", Module.class);
                addModuleExport.setAccessible(true);
            } catch (final NoSuchMethodException | SecurityException ex) {
                throw new RuntimeException(ex);
            }
            return null;
        };
        AccessController.doPrivileged(pa);
    }

    final void addModuleExport(final Module to) {
        try {
            addModuleExport.invoke(null, to);
        } catch (final IllegalAccessException |
                IllegalArgumentException |
                InvocationTargetException ex) {
            throw new RuntimeException(ex);
        }
    }

    protected static void checkPackageAccess(final String name) {
        final int i = name.lastIndexOf('.');
        if (i != -1) {
            final SecurityManager sm = System.getSecurityManager();
            if (sm != null) {
                final String pkgName = name.substring(0, i);
                switch (pkgName) {
                    case RUNTIME_PKG:
                    case RUNTIME_ARRAYS_PKG:
                    case RUNTIME_LINKER_PKG:
                    case OBJECTS_PKG:
                    case SCRIPTS_PKG:
                        // allow it.
                        break;
                    default:
                        sm.checkPackageAccess(pkgName);
                }
            }
        }
    }

    @Override
    protected PermissionCollection getPermissions(final CodeSource codesource) {
        final Permissions permCollection = new Permissions();
        for (final Permission perm : SCRIPT_PERMISSIONS) {
            permCollection.add(perm);
        }
        return permCollection;
    }

    /**
     * Create a secure URL class loader for the given classpath
     * @param classPath classpath for the loader to search from
     * @param parent the parent class loader for the new class loader
     * @return the class loader
     */
    static ClassLoader createClassLoader(final String classPath, final ClassLoader parent) {
        final URL[] urls = pathToURLs(classPath);
        return URLClassLoader.newInstance(urls, parent);
    }

    /*
     * Utility method for converting a search path string to an array
     * of directory and JAR file URLs.
     *
     * @param path the search path string
     * @return the resulting array of directory and JAR file URLs
     */
    private static URL[] pathToURLs(final String path) {
        final String[] components = path.split(File.pathSeparator);
        URL[] urls = new URL[components.length];
        int count = 0;
        while(count < components.length) {
            final URL url = fileToURL(new File(components[count]));
            if (url != null) {
                urls[count++] = url;
            }
        }
        if (urls.length != count) {
            final URL[] tmp = new URL[count];
            System.arraycopy(urls, 0, tmp, 0, count);
            urls = tmp;
        }
        return urls;
    }

    /*
     * Returns the directory or JAR file URL corresponding to the specified
     * local file name.
     *
     * @param file the File object
     * @return the resulting directory or JAR file URL, or null if unknown
     */
    private static URL fileToURL(final File file) {
        String name;
        try {
            name = file.getCanonicalPath();
        } catch (final IOException e) {
            name = file.getAbsolutePath();
        }
        name = name.replace(File.separatorChar, '/');
        if (!name.startsWith("/")) {
            name = "/" + name;
        }
        // If the file does not exist, then assume that it's a directory
        if (!file.isFile()) {
            name += "/";
        }
        try {
            return new URL("file", "", name);
        } catch (final MalformedURLException e) {
            throw new IllegalArgumentException("file");
        }
    }

    private static byte[] readModuleManipulatorBytes() {
        final PrivilegedAction<byte[]> pa = () -> {
            final String res = "/"+ MODULE_MANIPULATOR_NAME.replace('.', '/') + ".class";
            try (InputStream in = NashornLoader.class.getResourceAsStream(res)) {
                return in.readAllBytes();
            } catch (final IOException exp) {
                throw new UncheckedIOException(exp);
            }
        };
        return AccessController.doPrivileged(pa);
    }
}

