/*
 * Copyright (c) 2009, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.enterprise.naming;

import static com.sun.enterprise.naming.util.LogFacade.logger;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;

import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.NoInitialContextException;
import javax.naming.spi.InitialContextFactory;
import javax.naming.spi.InitialContextFactoryBuilder;
import javax.naming.spi.NamingManager;

import org.glassfish.hk2.api.PostConstruct;
import org.glassfish.hk2.api.PreDestroy;
import org.glassfish.hk2.runlevel.RunLevel;
import org.glassfish.internal.api.InitRunLevel;
import org.glassfish.internal.api.ServerContext;
import org.glassfish.logging.annotation.LogMessageInfo;
import org.jvnet.hk2.annotations.Service;

import com.sun.enterprise.naming.impl.SerialInitContextFactory;

import jakarta.inject.Inject;

/**
 * This is both a init run level service as well as our implementation of {@link InitialContextFactoryBuilder}. When GlassFish
 * starts up, this startup service configures NamingManager with appropriate builder by calling
 * {@link javax.naming.spi.NamingManager#setInitialContextFactoryBuilder}. Once the builder is setup, when ever new
 * InitialContext() is called, builder can either instantiate {@link SerialInitContextFactory}, which is our implementation of
 * {@link InitialContextFactory}, or any user specified InitialContextFactory class. While loading user specified class, it first
 * uses Thread's context class loader and then CommonClassLoader.
 *
 * Please note that this is setup as an init level service to ensure that JNDI subsystem is setup before applications are loaded.
 *
 * @author Sanjeeb.Sahoo@Sun.COM
 */
@Service
@RunLevel(value = InitRunLevel.VAL, mode = RunLevel.RUNLEVEL_MODE_NON_VALIDATING)
public class GlassFishNamingBuilder implements InitialContextFactoryBuilder, PostConstruct, PreDestroy {
    @LogMessageInfo(message = "Failed to load {0} using CommonClassLoader")
    public static final String FAILED_TO_LOAD_CLASS = "AS-NAMING-00001";

    @LogMessageInfo(message = "Fall back to INITIAL_CONTEXT_FACTORY {0}")
    private static final String FALL_BACK_INITIAL_CONTEXT_FACTORY = "AS-NAMING-00008";

    /**
     * We use a naming builder in order to enable use of JNDI in OSGi context, because the builder gives us desired hooks to create
     * appserver specific initial context without having to rely on thread's context class loader which is a unknown quantity in osgi
     * environment. Use of a builder can lead to some probelamatic scenarios as discussed in issue #11997, so we allow user to
     * disable it if they want. Having such configuration option is more of a workaround than a fix, but I have not been able to find
     * a better solution so far.
     */
    private static final String ALLOW_JNDI_FROM_OSGI = "com.sun.enterprise.naming.allowJndiLookupFromOSGi";

    @Inject
    private ServerContext serverContext;

    @Override
    public InitialContextFactory createInitialContextFactory(Hashtable<?, ?> environment) throws NamingException {
        if (environment != null) {
            // As per the documentation of Context.INITIAL_CONTEXT_FACTORY,
            // it represents a fully qualified class name.
            String className = (String) environment.get(Context.INITIAL_CONTEXT_FACTORY);

            if (className != null) {
                try {
                    return (InitialContextFactory) (loadClass(className).getDeclaredConstructor().newInstance());
                } catch (Exception e) {
                    if (className.startsWith("weblogic.jndi")) {
                        logger.log(INFO, FALL_BACK_INITIAL_CONTEXT_FACTORY,
                            "com.sun.enterprise.naming.impl.SerialInitContextFactory");
                    } else {
                        NoInitialContextException ne = new NoInitialContextException("Cannot instantiate class: " + className);
                        ne.setRootCause(e);
                        throw ne;
                    }
                }
            }
        }
        // default case
        return new SerialInitContextFactory();
    }

    private Class<?> loadClass(String className) throws ClassNotFoundException {
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();

        try {
            return Class.forName(className, true, contextClassLoader);
        } catch (ClassNotFoundException e) {
            // Not a significant error.  Try with common class loader instead.
            logger.logp(FINE, "GlassFishNamingBuilder", "loadClass", "Failed to load {0} using thread context class loader {1}",
                new Object[] { className, contextClassLoader });

            // Try using CommonClassLoader.
            ClassLoader commonClassLoader = serverContext.getCommonClassLoader();
            if (contextClassLoader != commonClassLoader) {
                try {
                    return Class.forName(className, true, commonClassLoader);
                } catch (ClassNotFoundException e2) {
                    logger.logp(WARNING, "GlassFishNamingBuilder", "loadClass", FAILED_TO_LOAD_CLASS, new Object[] { className });
                    throw e2;
                }
            }

            throw e;
        }
    }

    @Override
    public void postConstruct() {
        try {
            SecurityManager sm = System.getSecurityManager();
            if (sm != null) {
                try {
                    AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
                        @Override
                        public Void run() throws NamingException {
                            if (isUsingBuilder()) {
                                NamingManager.setInitialContextFactoryBuilder(GlassFishNamingBuilder.this);
                            }
                            return null; //Nothing to return
                        }
                    });
                } catch (PrivilegedActionException e) {
                    Object obj = e.getCause();
                    if (obj instanceof NamingException) {
                        throw (NamingException) obj;
                    }
                }
            } else if (isUsingBuilder()) {
                NamingManager.setInitialContextFactoryBuilder(this);
            }

        } catch (NamingException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void preDestroy() {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
                @Override
                public Void run() {
                    if (isUsingBuilder()) {
                        resetInitialContextFactoryBuilder();
                    }
                    return null;
                }
            });
        } else {
            if (isUsingBuilder()) {
                resetInitialContextFactoryBuilder();
            }
        }
    }

    private void resetInitialContextFactoryBuilder() {
        try {
            Field initctxFactoryBuilderField = NamingManager.class.getDeclaredField("initctx_factory_builder");
            initctxFactoryBuilderField.setAccessible(true);
            initctxFactoryBuilderField.set(null, null);
        } catch (ReflectiveOperationException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @return true if we are using NamingBuilder, else false.
     */
    private Boolean isUsingBuilder() {
        // We are using a system property, because NamingBuilder is a JDK wide singleton.
        return Boolean.valueOf(System.getProperty(ALLOW_JNDI_FROM_OSGI, "true"));
    }

}
