/**
* 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 static org.apache.hadoop.yarn.util.StringHelper.join;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.util.StringUtils;
import org.apache.hadoop.yarn.api.records.NodeLabel;
import org.apache.hadoop.yarn.nodelabels.RMNodeLabel;
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
import org.apache.hadoop.yarn.server.resourcemanager.nodelabels.RMNodeLabelsManager;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerHealth;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CSQueue;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.UserInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.CapacitySchedulerInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.CapacitySchedulerLeafQueueInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.CapacitySchedulerQueueInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.PartitionQueueCapacitiesInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.PartitionResourcesInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ResourceInfo;
import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
import org.apache.hadoop.yarn.server.webapp.AppBlock;
import org.apache.hadoop.yarn.util.Times;
import org.apache.hadoop.yarn.util.resource.Resources;
import org.apache.hadoop.yarn.webapp.ResponseInfo;
import org.apache.hadoop.yarn.webapp.SubView;
import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet;
import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet.DIV;
import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet.LI;
import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet.TABLE;
import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet.TBODY;
import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet.UL;
import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
import org.apache.hadoop.yarn.webapp.view.InfoBlock;

import com.google.inject.Inject;
import com.google.inject.servlet.RequestScoped;

class CapacitySchedulerPage extends RmView {
  static final String _Q = ".ui-state-default.ui-corner-all";
  static final float Q_MAX_WIDTH = 0.8f;
  static final float Q_STATS_POS = Q_MAX_WIDTH + 0.05f;
  static final String Q_END = "left:101%";
  static final String Q_GIVEN =
      "left:0%;background:none;border:1px dashed #BFBFBF";
  static final String Q_AUTO_CREATED = "background:#F4F0CB";
  static final String Q_OVER = "background:#FFA333";
  static final String Q_UNDER = "background:#5BD75B";
  static final String ACTIVE_USER = "background:#FFFF00"; // Yellow highlight

  @RequestScoped
  static class CSQInfo {
    CapacitySchedulerInfo csinfo;
    CapacitySchedulerQueueInfo qinfo;
    String label;
    boolean isExclusiveNodeLabel;
  }

  static class LeafQueueInfoBlock extends HtmlBlock {
    final CapacitySchedulerLeafQueueInfo lqinfo;
    private String nodeLabel;

    @Inject LeafQueueInfoBlock(ViewContext ctx, CSQInfo info) {
      super(ctx);
      lqinfo = (CapacitySchedulerLeafQueueInfo) info.qinfo;
      nodeLabel = info.label;
    }

    @Override
    protected void render(Block html) {
      if (nodeLabel == null) {
        renderLeafQueueInfoWithoutParition(html);
      } else {
        renderLeafQueueInfoWithPartition(html);
      }
    }

    private void renderLeafQueueInfoWithPartition(Block html) {
      String nodeLabelDisplay = nodeLabel.length() == 0
          ? NodeLabel.DEFAULT_NODE_LABEL_PARTITION : nodeLabel;
      // first display the queue's label specific details :
      ResponseInfo ri =
          info("\'" + lqinfo.getQueuePath().substring(5)
              + "\' Queue Status for Partition \'" + nodeLabelDisplay + "\'");
      renderQueueCapacityInfo(ri, nodeLabel);
      html.__(InfoBlock.class);
      // clear the info contents so this queue's info doesn't accumulate into
      // another queue's info
      ri.clear();

      // second display the queue specific details :
      ri =
          info("\'" + lqinfo.getQueuePath().substring(5) + "\' Queue Status")
              .__("Queue State:", lqinfo.getQueueState());
      renderCommonLeafQueueInfo(ri);

      html.__(InfoBlock.class);
      // clear the info contents so this queue's info doesn't accumulate into
      // another queue's info
      ri.clear();
    }

    private void renderLeafQueueInfoWithoutParition(Block html) {
      ResponseInfo ri =
          info("\'" + lqinfo.getQueuePath().substring(5) + "\' Queue Status")
              .__("Queue State:", lqinfo.getQueueState());
      renderQueueCapacityInfo(ri, "");
      renderCommonLeafQueueInfo(ri);
      html.__(InfoBlock.class);
      // clear the info contents so this queue's info doesn't accumulate into
      // another queue's info
      ri.clear();
    }

    private void renderQueueCapacityInfo(ResponseInfo ri, String label) {
      PartitionQueueCapacitiesInfo capacities =
          lqinfo.getCapacities().getPartitionQueueCapacitiesInfo(label);
      PartitionResourcesInfo resourceUsages =
          lqinfo.getResources().getPartitionResourceUsageInfo(label);

      // Get UserInfo from first user to calculate AM Resource Limit per user.
      ResourceInfo userAMResourceLimit = null;
      ArrayList<UserInfo> usersList = lqinfo.getUsers().getUsersList();
      if (!usersList.isEmpty()) {
        userAMResourceLimit = resourceUsages.getUserAmLimit();
      }
      // If no users are present or if AM limit per user doesn't exist, retrieve
      // AM Limit for that queue.
      if (userAMResourceLimit == null) {
        userAMResourceLimit = resourceUsages.getAMLimit();
      }
      ResourceInfo amUsed = (resourceUsages.getAmUsed() == null)
          ? new ResourceInfo(Resources.none())
          : resourceUsages.getAmUsed();
      ri.
          __("Used Capacity:",
              appendPercent(resourceUsages.getUsed(),
                  capacities.getUsedCapacity() / 100))
          .__(capacities.getWeight() != -1 ?
              "Configured Weight:" :
                  "Configured Capacity:",
              capacities.getWeight() != -1 ?
                  capacities.getWeight() :
                  capacities.getConfiguredMinResource() == null ?
                  Resources.none().toString() :
                  capacities.getConfiguredMinResource().toString())
          .__("Configured Max Capacity:",
              (capacities.getConfiguredMaxResource() == null
                  || capacities.getConfiguredMaxResource().getResource()
                      .equals(Resources.none()))
                          ? "unlimited"
                          : capacities.getConfiguredMaxResource().toString())
          .__("Effective Capacity:",
              appendPercent(capacities.getEffectiveMinResource(),
                  capacities.getCapacity() / 100))
          .__("Effective Max Capacity:",
              appendPercent(capacities.getEffectiveMaxResource(),
                  capacities.getMaxCapacity() / 100))
          .__("Absolute Used Capacity:",
              percent(capacities.getAbsoluteUsedCapacity() / 100))
          .__("Absolute Configured Capacity:",
              percent(capacities.getAbsoluteCapacity() / 100))
          .__("Absolute Configured Max Capacity:",
              percent(capacities.getAbsoluteMaxCapacity() / 100))
          .__("Used Resources:", resourceUsages.getUsed().toString())
          .__("Configured Max Application Master Limit:",
              StringUtils.format("%.1f", capacities.getMaxAMLimitPercentage()))
          .__("Max Application Master Resources:",
              resourceUsages.getAMLimit().toString())
          .__("Used Application Master Resources:", amUsed.toString())
          .__("Max Application Master Resources Per User:",
              userAMResourceLimit.toString());
    }

    private void renderCommonLeafQueueInfo(ResponseInfo ri) {
      ri.
          __("Num Schedulable Applications:", Integer.toString(lqinfo.getNumActiveApplications())).
          __("Num Non-Schedulable Applications:", Integer.toString(lqinfo.getNumPendingApplications())).
          __("Num Containers:", Integer.toString(lqinfo.getNumContainers())).
          __("Max Applications:", Integer.toString(lqinfo.getMaxApplications())).
          __("Max Applications Per User:", Integer.toString(lqinfo.getMaxApplicationsPerUser())).
          __("Configured Minimum User Limit Percent:", Integer.toString(lqinfo.getUserLimit()) + "%").
          __("Configured User Limit Factor:", lqinfo.getUserLimitFactor()).
          __("Accessible Node Labels:", StringUtils.join(",", lqinfo.getNodeLabels())).
          __("Ordering Policy: ", lqinfo.getOrderingPolicyDisplayName()).
          __("Preemption:",
              lqinfo.getPreemptionDisabled() ? "disabled" : "enabled").
          __("Intra-queue Preemption:", lqinfo.getIntraQueuePreemptionDisabled()
                  ? "disabled" : "enabled").
          __("Default Node Label Expression:",
              lqinfo.getDefaultNodeLabelExpression() == null
                  ? NodeLabel.DEFAULT_NODE_LABEL_PARTITION
                  : lqinfo.getDefaultNodeLabelExpression()).
          __("Default Application Priority:",
              Integer.toString(lqinfo.getDefaultApplicationPriority()));
    }
  }

  static class QueueUsersInfoBlock extends HtmlBlock {
    final CapacitySchedulerLeafQueueInfo lqinfo;
    private String nodeLabel;

    @Inject
    QueueUsersInfoBlock(ViewContext ctx, CSQInfo info) {
      super(ctx);
      lqinfo = (CapacitySchedulerLeafQueueInfo) info.qinfo;
      nodeLabel = info.label;
    }

    @Override
    protected void render(Block html) {
      TBODY<TABLE<Hamlet>> tbody =
          html.table("#userinfo").thead().$class("ui-widget-header").tr().th()
              .$class("ui-state-default").__("User Name").__().th()
              .$class("ui-state-default").__("Max Resource").__().th()
              .$class("ui-state-default").__("Weight").__().th()
              .$class("ui-state-default").__("Used Resource").__().th()
              .$class("ui-state-default").__("Max AM Resource").__().th()
              .$class("ui-state-default").__("Used AM Resource").__().th()
              .$class("ui-state-default").__("Schedulable Apps").__().th()
              .$class("ui-state-default").__("Non-Schedulable Apps").__().__().__()
              .tbody();

      PartitionResourcesInfo queueUsageResources =
          lqinfo.getResources().getPartitionResourceUsageInfo(
              nodeLabel == null ? "" : nodeLabel);

      ArrayList<UserInfo> users = lqinfo.getUsers().getUsersList();
      for (UserInfo userInfo : users) {
        ResourceInfo resourcesUsed = userInfo.getResourcesUsed();
        ResourceInfo userAMLimitPerPartition =
            queueUsageResources.getUserAmLimit();
        // If AM limit per user is null, use the AM limit for the queue level.
        if (userAMLimitPerPartition == null) {
          userAMLimitPerPartition = queueUsageResources.getAMLimit();
        }
        if (userInfo.getUserWeight() != 1.0) {
          userAMLimitPerPartition =
              new ResourceInfo(
                  Resources.multiply(userAMLimitPerPartition.getResource(),
                      userInfo.getUserWeight()));
        }
        if (nodeLabel != null) {
          resourcesUsed = userInfo.getResourceUsageInfo()
              .getPartitionResourceUsageInfo(nodeLabel).getUsed();
        }
        ResourceInfo amUsed = userInfo.getAMResourcesUsed();
        if (amUsed == null) {
          amUsed = new ResourceInfo(Resources.none());
        }
        String highlightIfAsking =
            userInfo.getIsActive() ? ACTIVE_USER : null;
        tbody.tr().$style(highlightIfAsking).td(userInfo.getUsername())
            .td(userInfo.getUserResourceLimit().toString())
            .td(String.valueOf(userInfo.getUserWeight()))
            .td(resourcesUsed.toString())
            .td(userAMLimitPerPartition.toString())
            .td(amUsed.toString())
            .td(Integer.toString(userInfo.getNumActiveApplications()))
            .td(Integer.toString(userInfo.getNumPendingApplications())).__();
      }

      html.div().$class("usersinfo").h5("Active Users Info").__();
      tbody.__().__();
    }
  }

  public static class QueueBlock extends HtmlBlock {
    final CSQInfo csqinfo;

    @Inject QueueBlock(CSQInfo info) {
      csqinfo = info;
    }

    @Override
    public void render(Block html) {
      ArrayList<CapacitySchedulerQueueInfo> subQueues = (csqinfo.qinfo == null)
          ? csqinfo.csinfo.getQueues().getQueueInfoList()
          : csqinfo.qinfo.getQueues().getQueueInfoList();

      UL<Hamlet> ul = html.ul("#pq");
      float used;
      float absCap;
      float absMaxCap;
      float absUsedCap;
      for (CapacitySchedulerQueueInfo info : subQueues) {
        String nodeLabel = (csqinfo.label == null) ? "" : csqinfo.label;
        //DEFAULT_NODE_LABEL_PARTITION is accessible to all queues
        //other exclsiveNodeLabels are accessible only if configured
        if (!nodeLabel.isEmpty()// i.e. its DEFAULT_NODE_LABEL_PARTITION
            && csqinfo.isExclusiveNodeLabel
            && !info.getNodeLabels().contains("*")
            && !info.getNodeLabels().contains(nodeLabel)) {
          continue;
        }
        PartitionQueueCapacitiesInfo partitionQueueCapsInfo = info
            .getCapacities().getPartitionQueueCapacitiesInfo(nodeLabel);
        used = partitionQueueCapsInfo.getUsedCapacity() / 100;
        absCap = partitionQueueCapsInfo.getAbsoluteCapacity() / 100;
        absMaxCap = partitionQueueCapsInfo.getAbsoluteMaxCapacity() / 100;
        absUsedCap = partitionQueueCapsInfo.getAbsoluteUsedCapacity() / 100;

        boolean isAutoCreatedLeafQueue = info.isLeafQueue() ?
            ((CapacitySchedulerLeafQueueInfo) info).isAutoCreatedLeafQueue()
            : false;
        float capPercent = absMaxCap == 0 ? 0 : absCap/absMaxCap;
        float usedCapPercent = absMaxCap == 0 ? 0 : absUsedCap/absMaxCap;

        String Q_WIDTH = width(absMaxCap * Q_MAX_WIDTH);
        LI<UL<Hamlet>> li = ul.
          li().
            a(_Q).$style(isAutoCreatedLeafQueue? join( Q_AUTO_CREATED, ";",
            Q_WIDTH)
            :  Q_WIDTH).
              $title(join("Absolute Capacity:", percent(absCap))).
              span().$style(join(Q_GIVEN, ";font-size:1px;", width(capPercent))).
            __('.').__().
              span().$style(join(width(usedCapPercent),
                ";font-size:1px;left:0%;", absUsedCap > absCap ? Q_OVER : Q_UNDER)).
            __('.').__().
              span(".q", "Queue: "+info.getQueuePath().substring(5)).__().
            span().$class("qstats").$style(left(Q_STATS_POS)).
            __(join(percent(used), " used")).__();

        csqinfo.qinfo = info;
        if (info.isLeafQueue()) {
          li.ul("#lq").li().__(LeafQueueInfoBlock.class).__().__();
          li.ul("#lq").li().__(QueueUsersInfoBlock.class).__().__();
        } else {
          li.__(QueueBlock.class);
        }
        li.__();
      }

      ul.__();
    }
  }

  static class QueuesBlock extends HtmlBlock {
    final CapacityScheduler cs;
    final CSQInfo csqinfo;
    private final ResourceManager rm;
    private List<RMNodeLabel> nodeLabelsInfo;

    @Inject QueuesBlock(ResourceManager rm, CSQInfo info) {
      cs = (CapacityScheduler) rm.getResourceScheduler();
      csqinfo = info;
      this.rm = rm;
      RMNodeLabelsManager nodeLabelManager =
          rm.getRMContext().getNodeLabelManager();
      nodeLabelsInfo = nodeLabelManager.pullRMNodeLabelsInfo();
    }

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

      UserGroupInformation callerUGI = this.getCallerUGI();
      boolean isAdmin = false;
      ApplicationACLsManager aclsManager = rm.getApplicationACLsManager();
      if (aclsManager.areACLsEnabled()) {
        if (callerUGI != null && aclsManager.isAdmin(callerUGI)) {
          isAdmin = true;
        }
      } else {
        isAdmin = true;
      }

      // only show button to dump CapacityScheduler debug logs to admins
      if (isAdmin) {
        html.div()
          .button()
          .$style(
              "border-style: solid; border-color: #000000; border-width: 1px;"
                  + " cursor: hand; cursor: pointer; border-radius: 4px")
          .$onclick("confirmAction()").b("Dump scheduler logs").__().select()
          .$id("time").option().$value("60").__("1 min").__().option()
          .$value("300").__("5 min").__().option().$value("600").__("10 min").__()
          .__().__();

        StringBuilder script = new StringBuilder();
        script
          .append("function confirmAction() {")
          .append(" b = confirm(\"Are you sure you wish to generate"
              + " scheduler logs?\");")
          .append(" if (b == true) {")
          .append(" var timePeriod = $(\"#time\").val();")
          .append(" $.ajax({")
          .append(" type: 'POST',")
          .append(" url: '/ws/v1/cluster/scheduler/logs',")
          .append(" contentType: 'text/plain',")
          .append(AppBlock.getCSRFHeaderString(rm.getConfig()))
          .append(" data: 'time=' + timePeriod,")
          .append(" dataType: 'text'")
          .append(" }).done(function(data){")
          .append(" setTimeout(function(){")
          .append(" alert(\"Scheduler log is being generated.\");")
          .append(" }, 1000);")
          .append(" }).fail(function(data){")
          .append(
              " alert(\"Scheduler log generation failed. Please check the"
                  + " ResourceManager log for more information.\");")
          .append(" console.log(data);").append(" });").append(" }")
          .append("}");

        html.script().$type("text/javascript").__(script.toString()).__();
      }

      UL<DIV<DIV<Hamlet>>> ul = html.
        div("#cs-wrapper.ui-widget").
          div(".ui-widget-header.ui-corner-top").
          __("Application Queues").__().
          div("#cs.ui-widget-content.ui-corner-bottom").
            ul();
      if (cs == null) {
        ul.
          li().
            a(_Q).$style(width(Q_MAX_WIDTH)).
              span().$style(Q_END).__("100% ").__().
              span(".q", "default").__().__();
      } else {
        ul.
          li().$style("margin-bottom: 1em").
            span().$style("font-weight: bold").__("Legend:").__().
            span().$class("qlegend ui-corner-all").$style(Q_GIVEN).
            __("Capacity").__().
            span().$class("qlegend ui-corner-all").$style(Q_UNDER).
            __("Used").__().
            span().$class("qlegend ui-corner-all").$style(Q_OVER).
            __("Used (over capacity)").__().
            span().$class("qlegend ui-corner-all ui-state-default").
              __("Max Capacity").__().
            span().$class("qlegend ui-corner-all").$style(ACTIVE_USER).
            __("Users Requesting Resources").__().
            span().$class("qlegend ui-corner-all").$style(Q_AUTO_CREATED).
            __("Auto Created Queues").__().
          __();

        float used = 0;

        CSQueue root = cs.getRootQueue();
        CapacitySchedulerInfo sinfo = new CapacitySchedulerInfo(root, cs);
        csqinfo.csinfo = sinfo;

        boolean hasAnyLabelLinkedToNM = false;
        if (null != nodeLabelsInfo) {
          for (RMNodeLabel label : nodeLabelsInfo) {
            if (label.getLabelName().length() == 0) {
              // Skip DEFAULT_LABEL
              continue;
            }
            if (label.getNumActiveNMs() > 0) {
              hasAnyLabelLinkedToNM = true;
              break;
            }
          }
        }
        if (!hasAnyLabelLinkedToNM) {
          used = sinfo.getUsedCapacity() / 100;
          //label is not enabled in the cluster or there's only "default" label,
          ul.li().
            a(_Q).$style(width(Q_MAX_WIDTH)).
              span().$style(join(width(used), ";left:0%;",
                  used > 1 ? Q_OVER : Q_UNDER)).__(".").__().
              span(".q", "Queue: root").__().
            span().$class("qstats").$style(left(Q_STATS_POS)).
              __(join(percent(used), " used")).__().
              __(QueueBlock.class).__();
        } else {
          for (RMNodeLabel label : nodeLabelsInfo) {
            csqinfo.qinfo = null;
            csqinfo.label = label.getLabelName();
            csqinfo.isExclusiveNodeLabel = label.getIsExclusive();
            String nodeLabelDisplay = csqinfo.label.length() == 0
                ? NodeLabel.DEFAULT_NODE_LABEL_PARTITION : csqinfo.label;
            PartitionQueueCapacitiesInfo capacities = sinfo.getCapacities()
                .getPartitionQueueCapacitiesInfo(csqinfo.label);
            used = capacities.getUsedCapacity() / 100;
            String partitionUiTag =
                "Partition: " + nodeLabelDisplay + " " + label.getResource();
            ul.li().
            a(_Q).$style(width(Q_MAX_WIDTH)).
              span().$style(join(width(used), ";left:0%;",
                  used > 1 ? Q_OVER : Q_UNDER)).__(".").__().
              span(".q", partitionUiTag).__().
            span().$class("qstats").$style(left(Q_STATS_POS)).
                __(join(percent(used), " used")).__().__();

            //for the queue hierarchy under label
            UL<Hamlet> underLabel = html.ul("#pq");
            underLabel.li().
            a(_Q).$style(width(Q_MAX_WIDTH)).
              span().$style(join(width(used), ";left:0%;",
                  used > 1 ? Q_OVER : Q_UNDER)).__(".").__().
              span(".q", "Queue: root").__().
            span().$class("qstats").$style(left(Q_STATS_POS)).
                __(join(percent(used), " used")).__().
                __(QueueBlock.class).__().__();
          }
        }
      }
      ul.__().__().
      script().$type("text/javascript").
          __("$('#cs').hide();").__().__().
          __(RMAppsBlock.class);
      html.__(HealthBlock.class);
    }
  }

  public static class HealthBlock extends HtmlBlock {

    final CapacityScheduler cs;

    @Inject
    HealthBlock(ResourceManager rm) {
      cs = (CapacityScheduler) rm.getResourceScheduler();
    }

    @Override
    public void render(HtmlBlock.Block html) {
      SchedulerHealth healthInfo = cs.getSchedulerHealth();
      DIV<Hamlet> div = html.div("#health");
      div.h4("Aggregate scheduler counts");
      TBODY<TABLE<DIV<Hamlet>>> tbody =
          div.table("#lastrun").thead().$class("ui-widget-header").tr().th()
            .$class("ui-state-default").__("Total Container Allocations(count)")
            .__().th().$class("ui-state-default")
            .__("Total Container Releases(count)").__().th()
            .$class("ui-state-default")
            .__("Total Fulfilled Reservations(count)").__().th()
            .$class("ui-state-default").__("Total Container Preemptions(count)")
            .__().__().__().tbody();
      tbody
        .$class("ui-widget-content")
        .tr()
        .td(
          String.valueOf(cs.getRootQueueMetrics()
            .getAggregateAllocatedContainers()))
        .td(
          String.valueOf(cs.getRootQueueMetrics()
            .getAggegatedReleasedContainers()))
        .td(healthInfo.getAggregateFulFilledReservationsCount().toString())
        .td(healthInfo.getAggregatePreemptionCount().toString()).__().__().__();
      div.h4("Last scheduler run");
      tbody =
          div.table("#lastrun").thead().$class("ui-widget-header").tr().th()
            .$class("ui-state-default").__("Time").__().th()
            .$class("ui-state-default").__("Allocations(count - resources)").__()
            .th().$class("ui-state-default").__("Reservations(count - resources)")
            .__().th().$class("ui-state-default").__("Releases(count - resources)")
            .__().__().__().tbody();
      tbody
        .$class("ui-widget-content")
        .tr()
        .td(Times.format(healthInfo.getLastSchedulerRunTime()))
        .td(
          healthInfo.getAllocationCount().toString() + " - "
              + healthInfo.getResourcesAllocated().toString())
        .td(
          healthInfo.getReservationCount().toString() + " - "
              + healthInfo.getResourcesReserved().toString())
        .td(
          healthInfo.getReleaseCount().toString() + " - "
              + healthInfo.getResourcesReleased().toString()).__().__().__();
      Map<String, SchedulerHealth.DetailedInformation> info = new HashMap<>();
      info.put("Allocation", healthInfo.getLastAllocationDetails());
      info.put("Reservation", healthInfo.getLastReservationDetails());
      info.put("Release", healthInfo.getLastReleaseDetails());
      info.put("Preemption", healthInfo.getLastPreemptionDetails());

      for (Map.Entry<String, SchedulerHealth.DetailedInformation> entry : info
        .entrySet()) {
        String containerId = "N/A";
        String nodeId = "N/A";
        String queue = "N/A";
        String table = "#" + entry.getKey();
        div.h4("Last " + entry.getKey());
        tbody =
            div.table(table).thead().$class("ui-widget-header").tr().th()
              .$class("ui-state-default").__("Time").__().th()
              .$class("ui-state-default").__("Container Id").__().th()
              .$class("ui-state-default").__("Node Id").__().th()
              .$class("ui-state-default").__("Queue").__().__().__().tbody();
        SchedulerHealth.DetailedInformation di = entry.getValue();
        if (di.getTimestamp() != 0) {
          if (di.getContainerId() != null) {
            containerId = di.getContainerId().toString();
          }
          if (di.getNodeId() != null) {
            nodeId = di.getNodeId().toString();
          }
          queue = di.getQueue();
        }
        tbody.$class("ui-widget-content").tr()
          .td(Times.format(di.getTimestamp())).td(containerId).td(nodeId)
          .td(queue).__().__().__();
      }
      div.__();
    }
  }

  @Override protected void postHead(Page.HTML<__> html) {
    html.
      style().$type("text/css").
        __("#cs { padding: 0.5em 0 1em 0; margin-bottom: 1em; position: relative }",
          "#cs ul { list-style: none }",
          "#cs a { font-weight: normal; margin: 2px; position: relative }",
          "#cs a span { font-weight: normal; font-size: 80% }",
          "#cs-wrapper .ui-widget-header { padding: 0.2em 0.5em }",
          ".qstats { font-weight: normal; font-size: 80%; position: absolute }",
          ".qlegend { font-weight: normal; padding: 0 1em; margin: 1em }",
          "table.info tr th {width: 50%}").__(). // to center info table
      script("/static/jt/jquery.jstree.js").
      script().$type("text/javascript").
        __("$(function() {",
          "  $('#cs a span').addClass('ui-corner-all').css('position', 'absolute');",
          "  $('#cs').bind('loaded.jstree', function (e, data) {",
          "    var callback = { call:reopenQueryNodes }",
          "    data.inst.open_node('#pq', callback);",
          "   }).",
          "    jstree({",
          "    core: { animation: 188, html_titles: true },",
          "    plugins: ['themeroller', 'html_data', 'ui'],",
          "    themeroller: { item_open: 'ui-icon-minus',",
          "      item_clsd: 'ui-icon-plus', item_leaf: 'ui-icon-gear'",
          "    }",
          "  });",
          "  $('#cs').bind('select_node.jstree', function(e, data) {",
          "    var q = $('.q', data.rslt.obj).first().text();",
          "    if (q == 'Queue: root') q = '';",
          "    else {",
          "      q = q.substr(q.lastIndexOf(':') + 2);",
          "      q = '^' + q.substr(q.lastIndexOf('.') + 1) + '$';",
          "    }",
          // Update this filter column index for queue if new columns are added
          // Current index for queue column is 5
          "    $('#apps').dataTable().fnFilter(q, 5, true);",
          "  });",
          "  $('#cs').show();",
          "});").__().
        __(SchedulerPageUtil.QueueBlockUtil.class);
  }

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

  static String appendPercent(ResourceInfo resourceInfo, float f) {
    if (resourceInfo == null) {
      return "";
    }
    return resourceInfo.toString() + " ("
        + StringUtils.formatPercent(f, 1) + ")";
  }

  static String percent(float f) {
    return StringUtils.formatPercent(f, 1);
  }

  static String width(float f) {
    return StringUtils.format("width:%.1f%%", f * 100);
  }

  static String left(float f) {
    return StringUtils.format("left:%.1f%%", f * 100);
  }
}
