/*
 * 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.htrace.impl;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.htrace.HTraceConfiguration;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.Locale;
import java.util.TreeSet;

/**
 * The HTrace process ID.<p/>
 *
 * HTrace process IDs are created from format strings.
 * Format strings contain variables which the ProcessId class will
 * replace with the correct values at runtime.<p/>
 *
 * <ul>
 * <li>${ip}: will be replaced with an ip address.</li>
 * <li>${pname}: will be replaced the process name obtained from java.</li>
 * </ul><p/>
 *
 * For example, the string "${pname}/${ip}" will be replaced with something
 * like: DataNode/192.168.0.1, assuming that the process' name is DataNode
 * and its IP address is 192.168.0.1.<p/>
 *
 * Process ID strings can contain backslashes as escapes.
 * For example, "\a" will map to "a".  "\${ip}" will map to the literal
 * string "${ip}", not the IP address.  A backslash itself can be escaped by a
 * preceding backslash.
 */
public final class ProcessId {
  private static final Log LOG = LogFactory.getLog(ProcessId.class);

  /**
   * The configuration key to use for process id
   */
  static final String PROCESS_ID_KEY = "process.id";

  /**
   * The default process ID to use if no other ID is configured.
   */
  private static final String DEFAULT_PROCESS_ID = "${pname}/${ip}";

  private final String processId;

  ProcessId(String fmt) {
    StringBuilder bld = new StringBuilder();
    StringBuilder varBld = null;
    boolean escaping = false;
    int varSeen = 0;
    for (int i = 0, len = fmt.length() ; i < len; i++) {
      char c = fmt.charAt(i);
      if (c == '\\') {
        if (!escaping) {
          escaping = true;
          continue;
        }
      }
      switch (varSeen) {
        case 0:
          if (c == '$') {
            if (!escaping) {
              varSeen = 1;
              continue;
            }
          }
          escaping = false;
          varSeen = 0;
          bld.append(c);
          break;
        case 1:
          if (c == '{') {
            if (!escaping) {
              varSeen = 2;
              varBld = new StringBuilder();
              continue;
            }
          }
          escaping = false;
          varSeen = 0;
          bld.append("$").append(c);
          break;
        default:
          if (c == '}') {
            if (!escaping) {
              String var = varBld.toString();
              bld.append(processShellVar(var));
              varBld = null;
              varSeen = 0;
              continue;
            }
          }
          escaping = false;
          varBld.append(c);
          varSeen++;
          break;
      }
    }
    if (varSeen > 0) {
      LOG.warn("Unterminated process ID substitution variable at the end " +
          "of format string " + fmt);
    }
    this.processId = bld.toString();
    if (LOG.isTraceEnabled()) {
      LOG.trace("ProcessID(fmt=" + fmt + "): computed process ID of \"" +
          this.processId + "\"");
    }
  }

  public ProcessId(HTraceConfiguration conf) {
    this(conf.get(PROCESS_ID_KEY, DEFAULT_PROCESS_ID));
  }

  private String processShellVar(String var) {
    if (var.equals("pname")) {
      return getProcessName();
    } else if (var.equals("ip")) {
      return getBestIpString();
    } else if (var.equals("pid")) {
      return Long.valueOf(getOsPid()).toString();
    } else {
      LOG.warn("unknown ProcessID variable " + var);
      return "";
    }
  }

  static String getProcessName() {
    String cmdLine = System.getProperty("sun.java.command");
    if (cmdLine != null && !cmdLine.isEmpty()) {
      String fullClassName = cmdLine.split("\\s+")[0];
      String[] classParts = fullClassName.split("\\.");
      cmdLine = classParts[classParts.length - 1];
    }
    return (cmdLine == null || cmdLine.isEmpty()) ? "Unknown" : cmdLine;
  }

  /**
   * Get the best IP address that represents this node.<p/>
   *
   * This is complicated since nodes can have multiple network interfaces,
   * and each network interface can have multiple IP addresses.  What we're
   * looking for here is an IP address that will serve to identify this node
   * to HTrace.  So we prefer site-local addresess (i.e. private ones on the
   * LAN) to publicly routable interfaces.  If there are multiple addresses
   * to choose from, we select the one which comes first in textual sort
   * order.  This should ensure that we at least consistently call each node
   * by a single name.
   */
  static String getBestIpString() {
    Enumeration<NetworkInterface> ifaces;
    try {
      ifaces = NetworkInterface.getNetworkInterfaces();
    } catch (SocketException e) {
      LOG.error("Error getting network interfaces", e);
      return "127.0.0.1";
    }
    TreeSet<String> siteLocalCandidates = new TreeSet<String>();
    TreeSet<String> candidates = new TreeSet<String>();
    while (ifaces.hasMoreElements()) {
      NetworkInterface iface = ifaces.nextElement();
      for (Enumeration<InetAddress> addrs =
               iface.getInetAddresses(); addrs.hasMoreElements();) {
        InetAddress addr = addrs.nextElement();
        if (!addr.isLoopbackAddress()) {
          if (addr.isSiteLocalAddress()) {
            siteLocalCandidates.add(addr.getHostAddress());
          } else {
            candidates.add(addr.getHostAddress());
          }
        }
      }
    }
    if (!siteLocalCandidates.isEmpty()) {
      return siteLocalCandidates.first();
    }
    if (!candidates.isEmpty()) {
      return candidates.first();
    }
    return "127.0.0.1";
  }

  /**
   * Get the process id from the operating system.<p/>
   *
   * Unfortunately, there is no simple method to get the process id in Java.
   * The approach we take here is to use the shell method (see
   * {ProcessId#getOsPidFromShellPpid}) unless we are on Windows, where the
   * shell is not available.  On Windows, we use
   * {ProcessId#getOsPidFromManagementFactory}, which depends on some
   * undocumented features of the JVM, but which doesn't require a shell.
   */
  static long getOsPid() {
    if ((System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH)).
        contains("windows")) {
      return getOsPidFromManagementFactory();
    } else {
      return getOsPidFromShellPpid();
    }
  }

  /**
   * Get the process ID by executing a shell and printing the PPID (parent
   * process ID).<p/>
   *
   * This method of getting the process ID doesn't depend on any undocumented
   * features of the virtual machine, and should work on almost any UNIX
   * operating system.
   */
  private static long getOsPidFromShellPpid() {
    Process p = null;
    StringBuilder sb = new StringBuilder();
    try {
      p = new ProcessBuilder("/usr/bin/env", "sh", "-c", "echo $PPID").
        redirectErrorStream(true).start();
      BufferedReader reader = new BufferedReader(
          new InputStreamReader(p.getInputStream()));
      String line = "";
      while ((line = reader.readLine()) != null) {
        sb.append(line.trim());
      }
      int exitVal = p.waitFor();
      if (exitVal != 0) {
        throw new IOException("Process exited with error code " +
            Integer.valueOf(exitVal).toString());
      }
    } catch (InterruptedException e) {
      LOG.error("Interrupted while getting operating system pid from " +
          "the shell.", e);
      return 0L;
    } catch (IOException e) {
      LOG.error("Error getting operating system pid from the shell.", e);
      return 0L;
    } finally {
      if (p != null) {
        p.destroy();
      }
    }
    try {
      return Long.parseLong(sb.toString());
    } catch (NumberFormatException e) {
      LOG.error("Error parsing operating system pid from the shell.", e);
      return 0L;
    }
  }

  /**
   * Get the process ID by looking at the name of the managed bean for the
   * runtime system of the Java virtual machine.<p/>
   *
   * Although this is undocumented, in the Oracle JVM this name is of the form
   * [OS_PROCESS_ID]@[HOSTNAME].
   */
  private static long getOsPidFromManagementFactory() {
    try {
      return Long.parseLong(ManagementFactory.getRuntimeMXBean().
          getName().split("@")[0]);
    } catch (NumberFormatException e) {
      LOG.error("Failed to get the operating system process ID from the name " +
          "of the managed bean for the JVM.", e);
      return 0L;
    }
  }

  public String get() {
    return processId;
  }
}
