/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You 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.apache.geode.internal.logging;

import static org.apache.geode.internal.logging.Banner.BannerHeader.CLASS_PATH;
import static org.apache.geode.internal.logging.Banner.BannerHeader.COMMAND_LINE_PARAMETERS;
import static org.apache.geode.internal.logging.Banner.BannerHeader.COMMUNICATIONS_VERSION;
import static org.apache.geode.internal.logging.Banner.BannerHeader.CURRENT_DIR;
import static org.apache.geode.internal.logging.Banner.BannerHeader.HOME_DIR;
import static org.apache.geode.internal.logging.Banner.BannerHeader.LIBRARY_PATH;
import static org.apache.geode.internal.logging.Banner.BannerHeader.LICENSE_START;
import static org.apache.geode.internal.logging.Banner.BannerHeader.LOG4J2_CONFIGURATION;
import static org.apache.geode.internal.logging.Banner.BannerHeader.PROCESS_ID;
import static org.apache.geode.internal.logging.Banner.BannerHeader.SYSTEM_PROPERTIES;
import static org.apache.geode.internal.logging.Banner.BannerHeader.USER;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.TreeMap;

import org.apache.geode.SystemFailure;
import org.apache.geode.distributed.internal.DistributionConfig;
import org.apache.geode.internal.GemFireVersion;
import org.apache.geode.internal.OSProcess;
import org.apache.geode.internal.Version;
import org.apache.geode.internal.VersionDescription;
import org.apache.geode.internal.util.ArgumentRedactor;

/**
 * Utility class to print banner information at manager startup.
 *
 * <p>
 * Banner should only be accessed from the Logging package or from Logging tests.
 */
public class Banner {

  public static final String SEPARATOR =
      "---------------------------------------------------------------------------";

  private final String configurationInfo;

  /**
   * @deprecated Please use {@link Banner(String)} instead. Banner should only be accessed from the
   *             Logging package or from Logging tests.
   */
  @Deprecated
  public Banner() {
    this(ConfigurationInfo.getConfigurationInfo());
  }

  public Banner(final String configurationInfo) {
    this.configurationInfo = configurationInfo;
  }

  public String getString() {
    return getString(null);
  }

  /**
   * Return a string containing the banner information.
   *
   * @param args possibly null list of command line arguments
   */
  public String getString(String[] args) {
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw);
    print(pw, args);
    pw.close();
    return sw.toString();
  }

  private void prettyPrintPath(String path, PrintWriter out) {
    if (path != null) {
      StringTokenizer st = new StringTokenizer(path, System.getProperty("path.separator"));
      while (st.hasMoreTokens()) {
        out.println("  " + st.nextToken());
      }
    }
  }

  /**
   * Print information about this process to the specified stream.
   *
   * @param args possibly null list of command line arguments
   */
  private void print(PrintWriter out, String args[]) {
    // Copy the system properties for printing. Some are given explicit lines, and
    // others are suppressed. Remove these keys, keeping those we want.
    Map sp = new TreeMap((Properties) System.getProperties().clone()); // fix for 46822
    Object userName = sp.get("user.name");
    Object userDir = sp.get("user.dir");
    Object userHome = sp.get("user.home");
    Object javaClassPath = sp.get("java.class.path");
    Object javaLibraryPath = sp.get("java.library.path");
    sp.remove("user.name");
    sp.remove("user.dir");
    sp.remove("user.home");
    sp.remove("java.class.path");
    sp.remove("java.library.path");
    sp.remove("os.name");
    sp.remove("os.arch");

    int processId = attemptToReadProcessId();
    short currentOrdinal = Version.CURRENT_ORDINAL;

    List<String> commandLineArguments = new ArrayList<>();
    RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
    if (runtimeBean != null) {
      // each argument is redacted below.
      commandLineArguments.addAll(runtimeBean.getInputArguments());
    }

    if (args != null && args.length != 0) {
      Collections.addAll(commandLineArguments, args);
    }

    // Print it all out.
    out.println();
    out.println(SEPARATOR);
    printASFLicense(out);
    out.println(SEPARATOR);
    GemFireVersion.print(out);
    out.println(COMMUNICATIONS_VERSION.displayValue() + ": " + currentOrdinal);
    out.println(PROCESS_ID.displayValue() + ": " + processId);
    out.println(USER.displayValue() + ": " + userName);
    out.println(CURRENT_DIR.displayValue() + ": " + userDir);
    out.println(HOME_DIR.displayValue() + ": " + userHome);

    if (!commandLineArguments.isEmpty()) {
      out.println(COMMAND_LINE_PARAMETERS.displayValue() + ":");
      for (String arg : commandLineArguments) {
        out.println("  " + ArgumentRedactor.redact(arg));
      }
    }

    out.println(CLASS_PATH.displayValue() + ":");
    prettyPrintPath((String) javaClassPath, out);
    out.println(LIBRARY_PATH.displayValue() + ":");
    prettyPrintPath((String) javaLibraryPath, out);

    if (Boolean.getBoolean(DistributionConfig.GEMFIRE_PREFIX + "disableSystemPropertyLogging")) {
      out.println("System property logging disabled.");
    } else {
      out.println(SYSTEM_PROPERTIES.displayValue() + ":");
      for (Object o : sp.entrySet()) {
        Entry me = (Entry) o;
        String key = me.getKey().toString();
        String value =
            ArgumentRedactor.redactArgumentIfNecessary(key, String.valueOf(me.getValue()));
        out.println("    " + key + " = " + value);
      }
      out.println(LOG4J2_CONFIGURATION.displayValue() + ":");
      out.println("    " + configurationInfo);
    }
    out.println(SEPARATOR);
  }

  /**
   * @return The PID of the current process, or -1 if the PID cannot be determined.
   */
  private int attemptToReadProcessId() {
    int processId = -1;
    try {
      processId = OSProcess.getId();
    } catch (VirtualMachineError err) {
      SystemFailure.initiateFailure(err);
      // If this ever returns, rethrow the error. We're poisoned
      // now, so don't let this thread continue.
      throw err;
    } catch (Throwable t) {
      // Whenever you catch Error or Throwable, you must also
      // catch VirtualMachineError (see above). However, there is
      // _still_ a possibility that you are dealing with a cascading
      // error condition, so you also need to check to see if the JVM
      // is still usable:
      SystemFailure.checkFailure();
    }
    return processId;
  }

  private void printASFLicense(PrintWriter out) {
    out.println("  ");
    out.println("  " + LICENSE_START.displayValue());
    out.println("  contributor license agreements.  See the NOTICE file distributed with this");
    out.println("  work for additional information regarding copyright ownership.");
    out.println("   ");
    out.println("  The ASF licenses this file to You under the Apache License, Version 2.0");
    out.println("  (the \"License\"); you may not use this file except in compliance with the");
    out.println("  License.  You may obtain a copy of the License at");
    out.println("  ");
    out.println("  http://www.apache.org/licenses/LICENSE-2.0");
    out.println("  ");
    out.println("  Unless required by applicable law or agreed to in writing, software");
    out.println("  distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT");
    out.println("  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the");
    out.println("  License for the specific language governing permissions and limitations");
    out.println("  under the License.");
    out.println("  ");
  }

  /**
   * The headers of the log {@link Banner}.
   */
  public enum BannerHeader {

    LICENSE_START("Licensed to the Apache Software Foundation (ASF) under one or more"),
    BUILD_DATE(VersionDescription.BUILD_DATE),
    BUILD_ID(VersionDescription.BUILD_ID),
    BUILD_JAVA_VERSION(VersionDescription.BUILD_JAVA_VERSION),
    BUILD_PLATFORM(VersionDescription.BUILD_PLATFORM),
    PRODUCT_NAME(VersionDescription.PRODUCT_NAME),
    PRODUCT_VERSION(VersionDescription.PRODUCT_VERSION),
    SOURCE_DATE(VersionDescription.SOURCE_DATE),
    SOURCE_REPOSITORY(VersionDescription.SOURCE_REPOSITORY),
    SOURCE_REVISION(VersionDescription.SOURCE_REVISION),
    RUNNING_ON(VersionDescription.RUNNING_ON),
    COMMUNICATIONS_VERSION("Communications version"),
    PROCESS_ID("Process ID"),
    USER("User"),
    CURRENT_DIR("Current dir"),
    HOME_DIR("Home dir"),
    COMMAND_LINE_PARAMETERS("Command Line Parameters"),
    CLASS_PATH("Class Path"),
    LIBRARY_PATH("Library Path"),
    SYSTEM_PROPERTIES("System Properties"),
    LOG4J2_CONFIGURATION("Log4J 2 Configuration");

    private final String displayValue;

    BannerHeader(String displayValue) {
      this.displayValue = displayValue;
    }

    public String displayValue() {
      return displayValue;
    }

    public static String[] displayValues() {
      String[] headerValues = new String[BannerHeader.values().length];
      int i = 0;
      for (BannerHeader bannerHeader : BannerHeader.values()) {
        headerValues[i] = bannerHeader.displayValue();
        i++;
      }
      return headerValues;
    }
  }
}
