/*
   * (non-Javadoc)
   *
   * @see
   * com.intel.stl.ui.monitor.tree.TreeUpater#updateNode(com.intel.stl.ui.
   * monitor.FVResourceNode, com.intel.stl.ui.monitor.FVResourceNode,
   * com.intel.stl.ui.monitor.FVTreeModel,
   * com.intel.stl.ui.common.IProgressObserver)
   */
  @Override
  protected void updateNode(
      FVResourceNode node,
      FVResourceNode parent,
      List<ITreeMonitor> monitors,
      IProgressObserver observer) {
    FVResourceNode refNode = nodeMap.get(node.getId());
    if (refNode == null) {
      throw new IllegalArgumentException("Couldn't find FVResourceNode " + node.getId());
    }

    Map<Integer, FVResourceNode> updated = new HashMap<Integer, FVResourceNode>();
    boolean hasStructureChange = false;
    int toUpdate = Math.min(refNode.getChildCount(), node.getChildCount());
    for (int i = 0; i < toUpdate; i++) {
      // update ports
      FVResourceNode port = node.getChildAt(i);
      FVResourceNode refPort = refNode.getChildAt(i);
      if (port.getType() != refPort.getType()) {
        boolean hasChanged = port.getType() != refPort.getType();
        if (hasChanged) {
          port.setType(refPort.getType());
          updated.put(i, port);
        }
      }
    }
    if (toUpdate < node.getChildCount()) {
      // remove ports
      for (int i = toUpdate; i < node.getChildCount(); i++) {
        node.removeChild(toUpdate);
        if (!hasStructureChange) {
          hasStructureChange = true;
        }
      }
    } else if (toUpdate < refNode.getChildCount()) {
      // add ports
      for (int i = toUpdate; i < refNode.getChildCount(); i++) {
        FVResourceNode port = refNode.getChildAt(i).copy();
        node.addChild(port);
        if (!hasStructureChange) {
          hasStructureChange = true;
        }
      }
    }

    if (monitors == null) {
      return;
    }

    if (hasStructureChange) {
      fireStructureChanged(monitors, node);
    } else if (!updated.isEmpty()) {
      for (Integer childIndex : updated.keySet()) {
        fireNodesUpdated(monitors, node, childIndex, updated.get(childIndex));
      }
    }
  }
  private boolean setPortStatus(FVResourceNode parentNode, FVResourceNode portNode) {
    int lid = parentNode.getId();
    int portNum = portNode.getId();
    boolean isActive = false;
    if (parentNode.getType() == TreeNodeType.SWITCH) {
      isActive = subnetApi.hasPort(lid, (short) portNum);
    } else {
      assert portNum > 0 : "HFI(" + parentNode + ") has invalid local port number " + portNum;
      isActive = subnetApi.hasLocalPort(lid, (short) portNum);
    }

    if (isActive) {
      if (portNode.getType() != TreeNodeType.ACTIVE_PORT) {
        portNode.setType(TreeNodeType.ACTIVE_PORT);
        return true;
      }
    } else {
      if (portNode.getType() != TreeNodeType.INACTIVE_PORT) {
        portNode.setType(TreeNodeType.INACTIVE_PORT);
        return true;
      }
    }
    return false;
  }
  /*
   * (non-Javadoc)
   *
   * @see
   * com.intel.stl.ui.monitor.tree.TreeUpater#updateNode(com.intel.stl.ui.
   * monitor.FVResourceNode, com.intel.stl.ui.monitor.FVResourceNode,
   * com.intel.stl.ui.monitor.FVTreeModel)
   */
  @Override
  protected void updateNode(
      FVResourceNode node,
      FVResourceNode parent,
      List<ITreeMonitor> monitors,
      IProgressObserver observer) {
    NodeRecordBean bean = nodeMap.get(node.getId());
    if (bean == null) {
      log.warn("Couldn't update tree because no node " + node.getId() + " found");
      return;
    }

    Map<Integer, FVResourceNode> updated = new HashMap<Integer, FVResourceNode>();
    boolean hasStructureChange = false;
    int numPorts = bean.getNodeInfo().getNumPorts();
    if (node.getType() == TreeNodeType.SWITCH) {
      numPorts += 1; // count in internal port
    }
    int toUpdate = Math.min(numPorts, node.getModelChildCount());
    for (int i = 0; i < toUpdate; i++) {
      // update ports
      FVResourceNode port = node.getModelChildAt(i);
      boolean statusChanged = setPortStatus(node, port);
      if (statusChanged) {
        updated.put(i, port);
      }
    }
    if (toUpdate < node.getModelChildCount()) {
      // remove ports
      while (node.getModelChildCount() > toUpdate) {
        node.removeChild(toUpdate);
        if (!hasStructureChange) {
          hasStructureChange = true;
        }
      }
    } else if (toUpdate < numPorts) {
      // add ports
      if (node.getType() == TreeNodeType.SWITCH) {
        numPorts -= 1;
        toUpdate -= 1;
      }
      for (int i = toUpdate + 1; i <= numPorts; i++) {
        FVResourceNode port = new FVResourceNode(Integer.toString(i), TreeNodeType.ACTIVE_PORT, i);

        // If the port is in the hash set, make it active
        // otherwise make it inactive
        setPortStatus(node, port);
        node.addChild(port);
        if (!hasStructureChange) {
          hasStructureChange = true;
        }
      }
    }

    if (monitors == null) {
      return;
    }

    if (hasStructureChange) {
      fireStructureChanged(monitors, node);
    } else if (!updated.isEmpty()) {
      for (Integer childIndex : updated.keySet()) {
        int viewIndex = node.getViewIndex(childIndex);
        fireNodesUpdated(monitors, node, viewIndex, updated.get(childIndex));
      }
    }
  }