/*
 * 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.
 */

/**
 * Code for drawing the enclosed rectangles that make up the physical plan for this topology.
 * Exports a single global function drawPhysicalPlan.
 */
(function (global) {
  var topo, instances, containers;

  function drawPhysicalPlan(planController, data, packingData, div_id, outerWidth, minHeight, cluster, environ, toponame) {
    var margin = {
      top: 50,
      right: 0,
      bottom: 20,
      left: 0
    };
    var width = outerWidth - margin.left - margin.right;

    instances = data.result.instances;
    containers = data.result.stmgrs;
    containerPlan = packingData.container_plans;

    var sptblt = Object.keys(data.result.spouts)
                       .concat(Object.keys(data.result.bolts));

    var color = d3.scale.ordinal().domain(sptblt.sort()).range(colors);

    for (var ck in containers) {
      var container = containers[ck];
      container.children = [];
    }

    for (var i in sptblt) {
      var comp = sptblt[i];
      for (var wk in instances) {
        var worker = instances[wk];
        if (worker.name === comp) {
          containers[worker.stmgrId].children.push(worker);
        }
      }
    }

    var containerList = _.values(containers);
    containerList.forEach(function (container) {
      // make ordering of instances the same in each container
      container.children = _.sortBy(container.children, 'name');
      // Parse index
      container.index = parseInt(container.id.split('-')[1]);
      // Search for resource config in packing plan
      container.required_resources = {
        'cpu': 0,
        'disk': 0,
        'ram': 0
      };
      for (var i in containerPlan) {
        var packing = containerPlan[i];
        if (packing.id === container.index) {
          container.required_resources = packing.required_resources;
        }
      }
    });

    // Sort the containers by their id so they are easier to find in the UI.
    containerList = _.sortBy(containerList, function(container) {
      return container.index;
    });

    var maxInstances = d3.max(containerList, function (d) {
      return d.children.length;
    });

    /**
     * Config paramaters for container/heron instance layout
     */

    // margin outside of each container as a fraction of the container width
    var containerMarginRatio = 0.08;
    // padding inside each container as a fraction of container width
    var containerPaddingRatio = 0.05;
    // margin around each heron instance as a faction of the instance width
    var instanceMarginRatio = 0.15;
    // smallest allowable width for a heron instance (below, this and we expand vertically)
    var minInstanceWidth = 6;
    // largest allowable width for heron instance (above this we shrink)
    var maxInstanceWith = 30;

    /**
     * Compute the container and instance sizes
     */

    var innerCols = Math.ceil(Math.sqrt(maxInstances));
    // compute the min columns allowed to keep instance size below limit
    var minContainerCols = Math.ceil(width / (innerCols * maxInstanceWith / (1 - 2 * instanceMarginRatio)));
    // compute the max columns allowed to keep instance size above min limit
    var maxContainerCols = Math.ceil(width / (innerCols * minInstanceWidth / (1 - 2 * instanceMarginRatio)));
    // compute # cols to give 50% more columns than rows, and bound it by max/min columns
    var desiredContainerCols = Math.ceil(Math.sqrt(containerList.length) * 1.5);
    var cols = Math.min(maxContainerCols, Math.max(minContainerCols, desiredContainerCols));
    // from there, compute the required number of rows and exact instance/container sizes...
    var rows = Math.ceil(containerList.length / cols);
    var innerRows = Math.ceil(maxInstances / innerCols);
    var containerWidth = (width / cols) * (1 - 2 * containerMarginRatio);
    var containerPadding = containerWidth * containerPaddingRatio;
    var containerMargin = containerMarginRatio * containerWidth;
    var instanceSize = (containerWidth - containerPadding * 2) / innerCols;
    var containerHeight = instanceSize * innerRows + containerPadding * 2;
    var height = (containerHeight + containerMargin * 2) * rows;
    var totalVisHeight = height + margin.top + margin.bottom;
    var totalVisWidth = Math.min(width, containerList.length * (containerWidth + containerMargin * 2));

    var svg = d3.select(div_id).text("").append("svg")
        .attr("width", totalVisWidth)
        .attr("height", totalVisHeight)
        .style("z-index", "1")
      .append("g")
        .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

    var textContainer = svg.append('text')
      .attr('x', (totalVisWidth - margin.left - margin.right) / 2)
      .attr('y', height + 25)
      .style('text-anchor', 'middle');

    var instance_tip = d3.tip()
        .attr('class', 'd3-tip main text-center')
        .offset([8, 0])
        .direction('s')
        .html(function(d) {
          var rows = window.pollingMetrics;
          var cols = window.pollingPeriods;
          var result = d.id + '<br>';
          if (d.currentMetric && _.isNumber(d.currentMetricValue)) {
            result += '<strong>' + d.currentMetric.metric.format(d.currentMetricValue) + '</strong>';
            result += ' ';
            result += d.currentMetric.metric.legendDescription;
            result += ' over last ';
            result += d.currentMetric.time.name;
            if (d.tooltipDetails) {
              result += d.tooltipDetails;
            }
          }
          return result;
        });

    var container_tip = d3.tip()
        .attr('class', 'd3-tip main text-center container')
        .offset([8, 0])
        .direction('s')
        .html(function (container) {
          return '<ul>' +
          '<li>cpu required: ' + container.required_resources.cpu + '</li>' +
          '<li>ram required: ' + (container.required_resources.ram / 1048576).toFixed(2) + 'MB</li>' +
          '<li>disk required: ' + (container.required_resources.disk / 1048576).toFixed(2) + 'MB</li>' +
          '</ul>';
        });

    var containerGs = svg.selectAll('.physical-plan')
        .data(containerList, function (d) { return d.id; })
        .enter()
      .append('g')
        .attr('class', 'physical-plan')
        .attr('transform', function (d, i) {
          var x = (i % cols) * (containerWidth + 2 * containerMargin) + containerMargin;
          var y = Math.floor(i / cols) * (containerHeight + 2 * containerMargin) + containerMargin;
          return 'translate(' + x + ',' + y + ')';
        });

    containerGs.append('rect')
        .attr('width', containerWidth)
        .attr('height', containerHeight)
        .attr('class', 'container')
        .on('mouseover', container_tip.show)
        .on('mouseout', container_tip.hide);

    containerGs.selectAll('.instance')
        .data(function (d) { return d.children; }, function (d) { return d.id; })
        .enter()
      .append('rect')
        .attr('class', 'instance')
        .style('fill', function (d) {
          d.defaultColor = color(d.name);
          d.color = d.color || d.defaultColor;
          return d.color;
        })
        .attr('width', instanceSize * (1 - 2 * instanceMarginRatio))
        .attr('height', instanceSize * (1 - 2 * instanceMarginRatio))
        .attr('x', function (d, i) { return containerPadding + (i % innerCols) * instanceSize + instanceSize * instanceMarginRatio; })
        .attr('y', function (d, i) { return containerPadding +Math.floor(i / innerCols) * instanceSize + instanceSize * instanceMarginRatio; })
        .on('mouseover', function (d) {
          planController.physicalComponentHoverOver(d, instance_tip);
        })
        .on('mouseout', function (d) {
          planController.physicalComponentHoverOut(d, instance_tip);
        })
        .on('click', function (d) {
          planController.physicalComponentClicked(d);
        });

    svg.call(instance_tip);
    svg.call(container_tip);
  }

  // Stash the old values for transition.
  function stash(d) {
    d.x0 = d.x;
    d.dx0 = d.dx;
  }

  global.drawPhysicalPlan = drawPhysicalPlan;
}(this));
