/**
 * 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.hadoop.yarn.server.resourcemanager.webapp;

import com.google.inject.Inject;
import org.apache.commons.text.StringEscapeUtils;
import org.apache.hadoop.util.StringUtils;
import org.apache.hadoop.yarn.api.records.NodeState;
import org.apache.hadoop.yarn.api.records.ResourceInformation;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.nodelabels.CommonNodeLabelsManager;
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
import org.apache.hadoop.yarn.server.resourcemanager.nodelabels.RMNodeLabelsManager;
import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNode;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodeInfo;
import org.apache.hadoop.yarn.util.Times;
import org.apache.hadoop.yarn.util.resource.ResourceUtils;
import org.apache.hadoop.yarn.webapp.SubView;
import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet;
import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet.TABLE;
import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet.TBODY;
import org.apache.hadoop.yarn.webapp.view.HtmlBlock;

import java.util.Collection;

import static org.apache.hadoop.yarn.webapp.YarnWebParams.NODE_LABEL;
import static org.apache.hadoop.yarn.webapp.YarnWebParams.NODE_STATE;
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES;
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES_ID;
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.initID;
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.tableInit;

class NodesPage extends RmView {

  static class NodesBlock extends HtmlBlock {
    final ResourceManager rm;
    private static final long BYTES_IN_MB = 1024 * 1024;
    private static final long BYTES_IN_GB = 1024 * 1024 * 1024;
    private static boolean opportunisticContainersEnabled;

    @Inject
    NodesBlock(ResourceManager rm, ViewContext ctx) {
      super(ctx);
      this.rm = rm;
      this.opportunisticContainersEnabled = YarnConfiguration
          .isOpportunisticContainerAllocationEnabled(
              this.rm.getRMContext().getYarnConfiguration());
    }

    @Override
    protected void render(Block html) {
      html.__(MetricsOverviewTable.class);

      ResourceScheduler sched = rm.getResourceScheduler();

      String type = $(NODE_STATE);
      String labelFilter = $(NODE_LABEL, CommonNodeLabelsManager.ANY).trim();
      Hamlet.TR<Hamlet.THEAD<TABLE<Hamlet>>> trbody =
          html.table("#nodes").thead().tr()
              .th(".nodelabels", "Node Labels")
              .th(".rack", "Rack")
              .th(".state", "Node State")
              .th(".nodeaddress", "Node Address")
              .th(".nodehttpaddress", "Node HTTP Address")
              .th(".lastHealthUpdate", "Last health-update")
              .th(".healthReport", "Health-report");

      if (!this.opportunisticContainersEnabled) {
        trbody.th(".containers", "Containers")
            .th(".allocationTags", "Allocation Tags")
            .th(".mem", "Mem Used")
            .th(".mem", "Mem Avail")
            .th(".mem", "Phys Mem Used %")
            .th(".vcores", "VCores Used")
            .th(".vcores", "VCores Avail")
            .th(".vcores", "Phys VCores Used %")
            .th(".gpus", "GPUs Used")
            .th(".gpus", "GPUs Avail");
      } else {
        trbody.th(".containers", "Running Containers (G)")
            .th(".allocationTags", "Allocation Tags")
            .th(".mem", "Mem Used (G)")
            .th(".mem", "Mem Avail (G)")
            .th(".mem", "Phys Mem Used %")
            .th(".vcores", "VCores Used (G)")
            .th(".vcores", "VCores Avail (G)")
            .th(".vcores", "Phys VCores Used %")
            .th(".gpus", "GPUs Used (G)")
            .th(".gpus", "GPUs Avail (G)")
            .th(".containers", "Running Containers (O)")
            .th(".mem", "Mem Used (O)")
            .th(".vcores", "VCores Used (O)")
            .th(".containers", "Queued Containers");
      }

      TBODY<TABLE<Hamlet>> tbody =
          trbody.th(".nodeManagerVersion", "Version").__().__().tbody();

      NodeState stateFilter = null;
      if (type != null && !type.isEmpty()) {
        stateFilter = NodeState.valueOf(StringUtils.toUpperCase(type));
      }
      Collection<RMNode> rmNodes = this.rm.getRMContext().getRMNodes().values();
      boolean isInactive = false;
      if (stateFilter != null) {
        switch (stateFilter) {
        case DECOMMISSIONED:
        case LOST:
        case REBOOTED:
        case SHUTDOWN:
          rmNodes = this.rm.getRMContext().getInactiveRMNodes().values();
          isInactive = true;
          break;
        case DECOMMISSIONING:
          // Do nothing
          break;
        default:
          LOG.debug("Unexpected state filter for inactive RM node");
        }
      }
      StringBuilder nodeTableData = new StringBuilder("[\n");
      for (RMNode ni : rmNodes) {
        if (stateFilter != null) {
          NodeState state = ni.getState();
          if (!stateFilter.equals(state)) {
            continue;
          }
        } else {
          // No filter. User is asking for all nodes. Make sure you skip the
          // unhealthy nodes.
          if (ni.getState() == NodeState.UNHEALTHY) {
            continue;
          }
        }
        // Besides state, we need to filter label as well.
        if (!labelFilter.equals(RMNodeLabelsManager.ANY)) {
          if (labelFilter.isEmpty()) {
            // Empty label filter means only shows nodes without label
            if (!ni.getNodeLabels().isEmpty()) {
              continue;
            }
          } else if (!ni.getNodeLabels().contains(labelFilter)) {
            // Only nodes have given label can show on web page.
            continue;
          }
        }
        NodeInfo info = new NodeInfo(ni, sched);
        int usedMemory = (int) info.getUsedMemory();
        int availableMemory = (int) info.getAvailableMemory();
        nodeTableData.append("[\"")
            .append(StringUtils.join(",", info.getNodeLabels())).append("\",\"")
            .append(info.getRack()).append("\",\"").append(info.getState())
            .append("\",\"").append(info.getNodeId());
        if (isInactive) {
          nodeTableData.append("\",\"").append("N/A").append("\",\"");
        } else {
          String httpAddress = info.getNodeHTTPAddress();
          nodeTableData.append("\",\"<a ").append("href='" + "//" + httpAddress)
              .append("'>").append(httpAddress).append("</a>\",").append("\"");
        }
        Integer gpuIndex = ResourceUtils.getResourceTypeIndex()
            .get(ResourceInformation.GPU_URI);
        long usedGPUs = 0;
        long availableGPUs = 0;
        if (gpuIndex != null && info.getUsedResource() != null
            && info.getAvailableResource() != null) {
          usedGPUs = info.getUsedResource().getResource()
              .getResourceValue(ResourceInformation.GPU_URI);
          availableGPUs = info.getAvailableResource().getResource()
              .getResourceValue(ResourceInformation.GPU_URI);
        }
        nodeTableData.append("<br title='")
            .append(String.valueOf(info.getLastHealthUpdate())).append("'>")
            .append(Times.format(info.getLastHealthUpdate())).append("\",\"")
            .append(StringEscapeUtils.escapeJava(info.getHealthReport())).append("\",\"")
            .append(String.valueOf(info.getNumContainers())).append("\",\"")
            .append(info.getAllocationTagsSummary()).append("\",\"")
            .append("<br title='").append(String.valueOf(usedMemory))
            .append("'>").append(StringUtils.byteDesc(usedMemory * BYTES_IN_MB))
            .append("\",\"").append("<br title='")
            .append(String.valueOf(availableMemory)).append("'>")
            .append(StringUtils.byteDesc(availableMemory * BYTES_IN_MB))
            .append("\",\"")
            .append(String.valueOf((int) info.getMemUtilization()))
            .append("\",\"")
            .append(String.valueOf(info.getUsedVirtualCores()))
            .append("\",\"")
            .append(String.valueOf(info.getAvailableVirtualCores()))
            .append("\",\"")
            .append(String.valueOf((int) info.getVcoreUtilization()))
            .append("\",\"")
            .append(String.valueOf(usedGPUs))
            .append("\",\"")
            .append(String.valueOf(availableGPUs))
            .append("\",\"");

        // If opportunistic containers are enabled, add extra fields.
        if (this.opportunisticContainersEnabled) {
          nodeTableData
              .append(String.valueOf(info.getNumRunningOpportContainers()))
              .append("\",\"").append("<br title='")
              .append(String.valueOf(info.getUsedMemoryOpportGB())).append("'>")
              .append(StringUtils.byteDesc(
                  info.getUsedMemoryOpportGB() * BYTES_IN_GB))
              .append("\",\"")
              .append(String.valueOf(info.getUsedVirtualCoresOpport()))
              .append("\",\"")
              .append(String.valueOf(info.getNumQueuedContainers()))
              .append("\",\"");
        }

        nodeTableData.append(ni.getNodeManagerVersion())
            .append("\"],\n");
      }
      if (nodeTableData.charAt(nodeTableData.length() - 2) == ',') {
        nodeTableData.delete(nodeTableData.length() - 2,
            nodeTableData.length() - 1);
      }
      nodeTableData.append("]");
      html.script().$type("text/javascript")
          .__("var nodeTableData=" + nodeTableData).__();
      tbody.__().__();
    }
  }

  @Override
  protected void preHead(Page.HTML<__> html) {
    commonPreHead(html);
    String type = $(NODE_STATE);
    String title = "Nodes of the cluster";
    if (type != null && !type.isEmpty()) {
      title = title + " (" + type + ")";
    }
    setTitle(title);
    set(DATATABLES_ID, "nodes");
    set(initID(DATATABLES, "nodes"), nodesTableInit());
    setTableStyles(html, "nodes", ".healthStatus {width:10em}",
        ".healthReport {width:10em}");
  }

  @Override
  protected Class<? extends SubView> content() {
    return NodesBlock.class;
  }

  private String nodesTableInit() {
    StringBuilder b = tableInit().append(", 'aaData': nodeTableData")
        .append(", bDeferRender: true").append(", bProcessing: true")
        .append(", aoColumnDefs: [")
        .append("{'bSearchable': false, 'aTargets': [ 7 ]}")
        .append(", {'sType': 'title-numeric', 'bSearchable': false, "
            + "'aTargets': [ 9, 10 ] }")
        .append(", {'sType': 'title-numeric', 'aTargets': [ 5 ]}")
        .append("]}");
    return b.toString();
  }
}
