/*
 * 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 {
  public 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;
  }
}
