/*
 * Copyright 2015-2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.glowroot.agent.util;

import java.io.IOException;
import java.util.jar.JarFile;
import java.util.jar.Manifest;

import com.google.common.base.StandardSystemProperty;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.glowroot.common.util.OnlyUsedByTests;

public class AppServerDetection {

    private static final Logger logger = LoggerFactory.getLogger(AppServerDetection.class);

    private static final @Nullable String MAIN_CLASS = buildMainClass();

    private AppServerDetection() {}

    public static boolean isIbmJvm() {
        return "IBM J9 VM".equals(StandardSystemProperty.JAVA_VM_NAME.value());
    }

    public static boolean isJRockitJvm() {
        return "Oracle JRockit(R)".equals(StandardSystemProperty.JAVA_VM_NAME.value());
    }

    static boolean isJBossModules() {
        return "org.jboss.modules.Main".equals(MAIN_CLASS);
    }

    static boolean isWildflySwarm() {
        return "org.wildfly.swarm.bootstrap.Main".equals(MAIN_CLASS);
    }

    static boolean isOldJBoss() {
        return "org.jboss.Main".equals(MAIN_CLASS);
    }

    static boolean isGlassfish() {
        return "com.sun.enterprise.glassfish.bootstrap.ASMain".equals(MAIN_CLASS);
    }

    static boolean isWebLogic() {
        return "weblogic.Server".equals(MAIN_CLASS);
    }

    static boolean isWebSphere() {
        return "com.ibm.wsspi.bootstrap.WSPreLauncher".equals(MAIN_CLASS);
    }

    @OnlyUsedByTests
    static @Nullable String buildMainClass() {
        String sunJavaCommand = System.getProperty("sun.java.command");
        if (sunJavaCommand == null) {
            return null;
        }
        int index = sunJavaCommand.indexOf(' ');
        if (index == -1) {
            return getMainClassFromJarIfNeeded(sunJavaCommand);
        }
        String firstArg = sunJavaCommand.substring(0, index);
        if (firstArg.startsWith("org.tanukisoftware.wrapper.")) {
            int nextIndex = sunJavaCommand.indexOf(' ', index + 1);
            if (nextIndex == -1) {
                return sunJavaCommand.substring(index + 1);
            }
            return sunJavaCommand.substring(index + 1, nextIndex);
        }
        return getMainClassFromJarIfNeeded(firstArg);
    }

    private static @Nullable String getMainClassFromJarIfNeeded(String mainClassOrJarFile) {
        if (!mainClassOrJarFile.endsWith(".jar")) {
            return mainClassOrJarFile;
        }
        Manifest manifest = null;
        try {
            // cannot use guava's Closer because JarFile doesn't implement Closeable prior to Java 7
            JarFile jarFile = new JarFile(mainClassOrJarFile);
            try {
                manifest = jarFile.getManifest();
            } finally {
                jarFile.close();
            }
        } catch (IOException e) {
            logger.debug(e.getMessage(), e);
        }
        return manifest == null ? null : manifest.getMainAttributes().getValue("Main-Class");
    }
}

@@ -909,58 +909,8 @@
 y;%0A%0A
-import org.glowroot.common.util.OnlyUsedByTests;%0A%0A
 publ
@@ -2065,28 +2065,15 @@
     
-@OnlyUsedByTests%0A   
+private
  sta
@@ -2180,24 +2180,331 @@
 .command%22);%0A
+        logger.debug(%22sun.java.command: %7B%7D%22, sunJavaCommand);%0A        String mainClass = buildMainClassInternal(sunJavaCommand);%0A        logger.debug(%22main class: %7B%7D%22, mainClass);%0A        return mainClass;%0A    %7D%0A%0A    private static @Nullable String buildMainClassInternal(@Nullable String sunJavaCommand) %7B%0A
         if (

Add debug logging for app server detection