content: /**
   * erlyberly, erlang trace debugger
   * Copyright (C) 2016 Andy Till
   *
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation, either version 3 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program. If not, see <http://www.gnu.org/licenses/>.
   */
  package erlyberly;
  
  import java.util.Map;
  import java.util.Objects;
  
  import com.ericsson.otp.erlang.OtpErlangAtom;
  import com.ericsson.otp.erlang.OtpErlangList;
  import com.ericsson.otp.erlang.OtpErlangLong;
  import com.ericsson.otp.erlang.OtpErlangString;
  
  import javafx.beans.property.LongProperty;
  import javafx.beans.property.SimpleLongProperty;
  import javafx.beans.property.SimpleStringProperty;
  import javafx.beans.property.StringProperty;
  
  /**
   * Domain object for an erlang process.
   */
  public class ProcInfo implements Comparable<ProcInfo> {
  
      private static final OtpErlangAtom TOTAL_HEAP_SIZE_ATOM = new OtpErlangAtom("total_heap_size");
  
      private static final OtpErlangAtom STACK_SIZE_ATOM = new OtpErlangAtom("stack_size");
  
      private static final OtpErlangAtom HEAP_SIZE_ATOM = new OtpErlangAtom("heap_size");
  
      private static final OtpErlangAtom MSG_QUEUE_LEN_ATOM = new OtpErlangAtom("message_queue_len");
  
      private static final OtpErlangList EMPTY_LIST = new OtpErlangList();
  
      private static final OtpErlangAtom REGISTERED_NAME_ATOM = new OtpErlangAtom("registered_name");
  
      private static final OtpErlangAtom GLOBAL_NAME_ATOM = new OtpErlangAtom("global_name");
  
      private static final OtpErlangAtom PID_ATOM = new OtpErlangAtom("pid");
  
      private static final OtpErlangAtom REDUCTIONS_ATOM = new OtpErlangAtom("reductions");
  
      private StringProperty pid;
  
      private StringProperty processName;
  
      private LongProperty reductions;
  
      private LongProperty msgQueueLen;
  
      private LongProperty heapSize;
  
      private LongProperty stackSize;
  
      private LongProperty totalHeapSize;
  
      public void setTotalHeapSize(long value) {
          totalHeapSizeProperty().set(value);
      }
  
      public long getTotalHeapSize() {
          return totalHeapSizeProperty().get();
      }
  
      public LongProperty totalHeapSizeProperty() {
          if (totalHeapSize == null)
              totalHeapSize = new SimpleLongProperty(this, "totalHeapSize");
          return totalHeapSize;
      }
  
      public void setStackSize(long value) {
          stackSizeProperty().set(value);
      }
  
      public long getStackSize() {
          return stackSizeProperty().get();
      }
  
      public LongProperty stackSizeProperty() {
          if (stackSize == null)
              stackSize = new SimpleLongProperty(this, "stackSize");
          return stackSize;
      }
  
      public void setHeapSize(long value) {
          heapSizeProperty().set(value);
      }
  
      public long getHeapSize() {
          return heapSizeProperty().get();
      }
  
      public LongProperty heapSizeProperty() {
          if (heapSize == null)
              heapSize = new SimpleLongProperty(this, "msgQueueLen");
          return heapSize;
      }
  
      public void setMsgQueueLen(long value) {
          msgQueueLenProperty().set(value);
      }
  
      public long getMsgQueueLen() {
          return msgQueueLenProperty().get();
      }
  
      public LongProperty msgQueueLenProperty() {
          if (msgQueueLen == null)
              msgQueueLen = new SimpleLongProperty(this, "msgQueueLen");
          return msgQueueLen;
      }
  
      public void setPid(String value) {
          pidProperty().set(value);
      }
  
      public String getPid() {
          return pidProperty().get();
      }
  
      public StringProperty pidProperty() {
          if (pid == null)
              pid = new SimpleStringProperty(this, "pid");
          return pid;
      }
  
      public void setProcessName(String value) {
          processNameProperty().set(value);
      }
  
      public String getProcessName() {
          return processNameProperty().get();
      }
  
      public StringProperty processNameProperty() {
          if (processName == null)
              processName = new SimpleStringProperty(this, "processName");
          return processName;
      }
  
      public void setReductions(long value) {
          reductionsProperty().set(value);
      }
  
      public long getReductions() {
          return reductionsProperty().get();
      }
  
      public LongProperty reductionsProperty() {
          if (reductions == null)
              reductions = new SimpleLongProperty(this, "reductions");
          return reductions;
      }
  
      public static ProcInfo toProcessInfo(Map<Object, Object> propList) {
          Object processName = propList.get(REGISTERED_NAME_ATOM);
          Object pid = ((OtpErlangString) propList.get(PID_ATOM)).stringValue();
  
          if(EMPTY_LIST.equals(processName)) {
              processName = "";
          }
  
          ProcInfo processInfo;
  
          processInfo = new ProcInfo();
          String localName = Objects.toString(processName, "");
          String globalName = Objects.toString(propList.get(GLOBAL_NAME_ATOM), "");
          processInfo.setProcessName(localName + ("".equals(localName) ? "" : " ") + ("".equals(globalName) ? "" : "(" + globalName + ")"));
          processInfo.setPid(Objects.toString(pid, ""));
          processInfo.setReductions(toLong(propList.get(REDUCTIONS_ATOM)));
          processInfo.setMsgQueueLen(toLong(propList.get(MSG_QUEUE_LEN_ATOM)));
          processInfo.setHeapSize(toLong(propList.get(HEAP_SIZE_ATOM)));
          processInfo.setStackSize(toLong(propList.get(STACK_SIZE_ATOM)));
          processInfo.setTotalHeapSize(toLong(propList.get(TOTAL_HEAP_SIZE_ATOM)));
  
          return processInfo;
      }
  
      private static long toLong(Object object) {
          if (object instanceof OtpErlangLong) {
              return ((OtpErlangLong) object).longValue();
          }
          return 0;
      }
  
      /**
       * We shouldn't need to implement this but sometimes {@link TableView}
       * attempts to sort the {@link ProcInfo} objects itself and tries to cast
       * {@link ProcInfo} to {@link Comparable}.
       * <p>
       * To avoid this exception we're just implementing comparable even if it
       * gives the wrong sort to what the user expected.
       */
      @Override
      public int compareTo(ProcInfo o) {
          return getProcessName().compareTo(o.getProcessName());
      }
  
      public String getShortName() {
          String processName2 = getProcessName();
          if(processName2 != null && !"".equals(getProcessName()))
              return getProcessName();
          return getPid();
      }
  }
  