/*
 * Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2015 IBM Corporation. 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,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     01/05/2015 Rick Curtis
//       - 455683: Automatically detect target server
//     04/24/2015 Rick Curtis
//       - 465452: Throw ServerPlatformException rather than NPE on create null platformClass
package org.eclipse.persistence.platform.server;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.exceptions.ServerPlatformException;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.security.PrivilegedGetConstructorFor;
import org.eclipse.persistence.internal.security.PrivilegedInvokeConstructor;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.PropertiesHandler;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.platform.server.glassfish.GlassfishPlatformDetector;
import org.eclipse.persistence.platform.server.was.WebSpherePlatformDetector;
import org.eclipse.persistence.platform.server.wls.WebLogicPlatformDetector;
import org.eclipse.persistence.sessions.DatabaseSession;

/**
 * A utility class to interact with ServerPlatforms.
 */
public final class ServerPlatformUtils {
    private static final List<ServerPlatformDetector> PLATFORMS = new ArrayList<ServerPlatformDetector>() {{
        add(new NoServerPlatformDetector());
        add(new WebSpherePlatformDetector());
        add(new WebLogicPlatformDetector());
        add(new GlassfishPlatformDetector());
    }};

    private static final String UNKNOWN_MARKER = "UNKNOWN";
    private static String SERVER_PLATFORM_CLS;

    private ServerPlatformUtils() {
        // no instance please
    }

    /**
     * @return The target-server class string that represents platform that is
     *         currently running. Return null if unknown.
     */
    public static String detectServerPlatform(AbstractSession session) {
        if (SERVER_PLATFORM_CLS == null) {
            for (ServerPlatformDetector server : PLATFORMS) {
                String res = server.checkPlatform();
                if (res != null) {
                    // Convert property values to platform class
                    SERVER_PLATFORM_CLS = PropertiesHandler.getPropertyValue(PersistenceUnitProperties.TARGET_SERVER, res);
                    break;
                }
            }
            // If we didn't detect a server, use the unknown marker so we don't
            // continually try to detect the platform.
            if (SERVER_PLATFORM_CLS == null) {
                SERVER_PLATFORM_CLS = UNKNOWN_MARKER;
            }
        }

        if (SERVER_PLATFORM_CLS == UNKNOWN_MARKER) {
            return null;
        } else {
            //https://bugs.eclipse.org/bugs/show_bug.cgi?id=476018
            //log message only when we know how loggers were set up
            if (session != null) {
                session.log(SessionLog.FINER, SessionLog.SERVER, "detect_server_platform", SERVER_PLATFORM_CLS);
            } else {
                AbstractSessionLog.getLog().log(SessionLog.FINER, SessionLog.SERVER, "detect_server_platform", SERVER_PLATFORM_CLS);
            }
            return SERVER_PLATFORM_CLS;
        }
    }

    /**
     * Create an instance of {@link ServerPlatform} from parameters passed in.
     *
     * @param session {@link DatabaseSession} which will be passed to the constructor of {@link ServerPlatform}
     * @param platformClass fully qualified name of the {@link ServerPlatform} implementation to initialize
     * @param loader {@link ClassLoader} to look up given platformClass
     *
     * @return initialized instance of {@link ServerPlatform}
     * @throws ServerPlatformException if supplied platformClass is not found, can not be initialized, or is null.
     *
     * @see ServerPlatformBase#ServerPlatformBase(DatabaseSession)
     */
    public static ServerPlatform createServerPlatform(DatabaseSession session, String platformClass, ClassLoader loader) {
        if (platformClass == null) {
            throw ServerPlatformException.invalidServerPlatformClass(null, null);
        }
        Class cls = null;
        try {
            //try the supplied classloader
            cls = findClass(platformClass, loader);
        } catch (ClassNotFoundException | PrivilegedActionException ex) {
            //fallback to EL loader
            ClassLoader cl = ServerPlatformUtils.class.getClassLoader();
            if (loader != cl) {
                try {
                    cls = findClass(platformClass, cl);
                } catch (ClassNotFoundException | PrivilegedActionException ex1) {
                    //ignore, throw first exception
                    throw ServerPlatformException.serverPlatformClassNotFound(platformClass, ex);
                }
            } else {
                throw ServerPlatformException.serverPlatformClassNotFound(platformClass, ex);
            }
        }
        final Class[] paramTypes = new Class[] { DatabaseSession.class };
        final Object[] params = new Object[] { session };
        ServerPlatform platform = null;
        if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
            try {
                Constructor constructor = AccessController.doPrivileged(
                        new PrivilegedGetConstructorFor(cls, paramTypes, false));
                platform = (ServerPlatform) AccessController.doPrivileged(
                        new PrivilegedInvokeConstructor(constructor, params));
            } catch (PrivilegedActionException ex) {
                throw ServerPlatformException.invalidServerPlatformClass(platformClass, ex);
            }
        } else {
            try {
                Constructor constructor = PrivilegedAccessHelper.getConstructorFor(cls, paramTypes, false);
                platform = (ServerPlatform) PrivilegedAccessHelper.invokeConstructor(constructor, params);
            } catch (NoSuchMethodException | IllegalAccessException
                    | InvocationTargetException | InstantiationException ex) {
                throw ServerPlatformException.invalidServerPlatformClass(platformClass, ex);
            }
        }
        return platform;
    }

    private static Class findClass(String className, ClassLoader loader) throws ClassNotFoundException, PrivilegedActionException {
        if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
            return AccessController.doPrivileged(new PrivilegedClassForName(className, false, loader));
        } else {
            return PrivilegedAccessHelper.getClassForName(className, false, loader);
        }
    }
}
