(function () {
  'use strict';

  const shapes = {
    cloud: ' M 79.72 49.60 C 86.00 37.29 98.57 29.01 111.96 26.42 C 124.27 24.11 137.53 26.15 148.18 32.90 C 158.08 38.78 165.39 48.87 167.65 60.20 C 176.20 57.90 185.14 56.01 194.00 57.73 C 206.08 59.59 217.92 66.01 224.37 76.66 C 227.51 81.54 228.85 87.33 229.23 93.06 C 237.59 93.33 246.22 95.10 253.04 100.19 C 256.69 103.13 259.87 107.67 258.91 112.59 C 257.95 118.43 252.78 122.38 247.78 124.82 C 235.27 130.43 220.23 130.09 207.98 123.93 C 199.33 127.88 189.76 129.43 180.30 128.57 C 173.70 139.92 161.70 147.65 148.86 149.93 C 133.10 153.26 116.06 148.15 104.42 137.08 C 92.98 143.04 78.96 143.87 66.97 139.04 C 57.75 135.41 49.70 128.00 46.60 118.43 C 43.87 109.95 45.81 100.29 51.30 93.32 C 57.38 85.18 67.10 80.44 76.99 78.89 C 74.38 69.20 74.87 58.52 79.72 49.60 Z'
  }

  var computeNodeId = 0;
  var instanceId = 0;

  angular.module('xos.diagnostic')
  .service('NodeDrawer', function(d3, serviceTopologyConfig, RackHelper, lodash){

    var _this = this;

    this.addNetworks = (nodes) => {
      nodes.append('path')
      .attr({
        d: shapes.cloud,
        transform: 'translate(-63, -52), scale(0.5)',
        class: 'cloud'
      });

      nodes.append('text')
      .attr({
        'text-anchor': 'middle',
        y: -5,
        x: 5,
      })
      .text(d => d.name)

      nodes.append('text')
      .attr({
        'text-anchor': 'middle',
        y: 8,
        x: 5,
        class: 'small'
      })
      .text(d => d.subtitle)

      nodes.each(function(n){
        let currentNode = d3.select(this);
        // cicle trouch node to add Tags and Public IP
        if(n.name === 'LAN' && angular.isDefined(n.subscriberTag)){
          currentNode.append('text')
          .attr({
            'text-anchor': 'middle',
            y: 40
          })
          .text(() => `C-Tag: ${n.subscriberTag.cTag}`);

          currentNode.append('text')
          .attr({
            'text-anchor': 'middle',
            y: 60
          })
          .text(() => `S-Tag: ${n.subscriberTag.sTag}`);
        }

        if(n.name === 'WAN' && angular.isDefined(n.subscriberIP)){
          currentNode.append('text')
          .attr({
            'text-anchor': 'middle',
            y: 40
          })
          .text(() => `Public IP: ${n.subscriberIP}`);
        }
      });
    }

    this.addRack = (nodes) => {

      // loop because of D3
      // rack will be only one
      nodes.each(d => {
        let [w, h] = RackHelper.getRackSize(d.computeNodes);

        // TODO update instead of delete and redraw
        nodes.select('g').remove();

        let rack = nodes
        .append('g');

        rack
        .attr({
          transform: `translate(0,0)`
        })
        .transition()
        .duration(serviceTopologyConfig.duration)
        .attr({
          transform: () => `translate(${- (w / 2)}, ${- (h / 2)})`
        });

        rack
        .append('rect')
        .attr({
          width: 0,
          height: 0
        })
        .transition()
        .duration(serviceTopologyConfig.duration)
        .attr({
          width: w,
          height: h
        });

        rack.append('text')
        .attr({
          'text-anchor': 'middle',
          y: - 10,
          x: w / 2,
          opacity: 0
        })
        .text(d => d.name)
        .transition()
        .duration(serviceTopologyConfig.duration)
        .attr({
          opacity: 1
        })

        this.drawComputeNodes(rack, d.computeNodes);

      });

    };

    this.drawComputeNodes = (container, nodes) => {
      
      let elements = container.selectAll('.compute-nodes')
      .data(nodes, d => {
        if(!angular.isString(d.d3Id)){
          d.d3Id = `compute-node-${++computeNodeId}`;
        }
        return d.d3Id;
      });

      let {width, height} = container.node().getBoundingClientRect();

      var nodeContainer = elements.enter().append('g');

      nodeContainer
      .attr({
        transform: `translate(${width / 2}, ${ height / 2})`,
        class: 'compute-node',
      })
      .transition()
      .duration(serviceTopologyConfig.duration)
      .attr({
        transform: (d) => `translate(${RackHelper.getComputeNodePosition(nodes, d.d3Id.replace('compute-node-', '') - 1)})`
      });

      nodeContainer.append('rect')
      .attr({
        width: 0,
        height: 0
      })
      .transition()
      .duration(serviceTopologyConfig.duration)
      .attr({
        width: d => RackHelper.getComputeNodeSize(d.instances)[0],
        height: d => RackHelper.getComputeNodeSize(d.instances)[1],
      });

      nodeContainer.append('text')
      .attr({
        'text-anchor': 'start',
        y: 15, //FIXME
        x: 10, //FIXME
        opacity: 0
      })
      .text(d => d.humanReadableName.split('.')[0])
      .transition()
      .duration(serviceTopologyConfig.duration)
      .attr({
        opacity: 1
      })

      // if there are Compute Nodes
      if(nodeContainer.length > 0){
        // draw instances for each compute node
        nodeContainer.each(function(a){
          _this.drawInstances(d3.select(this), a.instances);
        })
      }

    };

    // NOTE Stripping unuseful names to shorten labels.
    // This is not elegant
    const formatInstanceName = (name) => {
      return name
        .replace('app_', '')
        .replace('service_', '')
        // .replace('ovs_', '')
        .replace('mysite_', '')
        .replace('_instance', '');
    };

    const getInstanceStatusColor = (instance) => {
      function startWith(val, string){
        return string.substring(0, val.length) === val;
      }

      if(startWith('0 - ', instance.backend_status)){
        return 'provisioning';
      }
      if(startWith('1 - ', instance.backend_status)){
        return 'good';
      }
      if(startWith('2 - ', instance.backend_status)){
        return 'bad';
      }
      else {
        return '';
      }
    };

    const drawContainer = (container, docker) => {

      const containerBox = container.append('g')
        .attr({
          class: 'container',
          transform: `translate(${serviceTopologyConfig.instance.margin}, 115)`
        });

      containerBox.append('rect')
        .attr({
          width: 250 - (serviceTopologyConfig.container.margin * 2),
          height: serviceTopologyConfig.container.height,
        });

      containerBox.append('text')
        .attr({
          y: 20,
          x: serviceTopologyConfig.instance.margin,
          class: 'name'
        })
        .text(docker.name)

      // add stats
      const interestingMeters = ['memory', 'memory.usage', 'cpu_util'];

      interestingMeters.forEach((m, i) => {
        const meter = lodash.find(docker.stats, {meter: m});
        // if there is no meter stats skip rendering
        if(!angular.isDefined(meter)){
          return;
        }
        containerBox.append('text')
        .attr({
          y: 40 + (i * 15),
          x: serviceTopologyConfig.instance.margin,
          opacity: 0
        })
        .text(`${meter.description}: ${Math.round(meter.value)} ${meter.unit}`)
        .transition()
        .duration(serviceTopologyConfig.duration)
        .attr({
          opacity: 1
        });
      });

      // add port stats
      const ports = ['eth0', 'eth1'];
      const interestingPortMeters = [
        {
          meter: 'network.incoming.bytes.rate',
          label: 'Incoming'
        },
        {
          meter: 'network.outgoing.bytes.rate',
          label: 'Outgoing'
        }
      ];
      
      ports.forEach((p, j) => {

        // if there are no port stats skip rendering
        if(docker.port[p].length === 0){
          return;
        }

        containerBox.append('text')
        .attr({
          y: 90,
          x: serviceTopologyConfig.instance.margin + (120 * j),
          class: 'name'
        })
        .text(`${docker.name}-${p}`)

        interestingPortMeters.forEach((m, i) => {

          const meter = lodash.find(docker.port[p], {meter: m.meter});
          // if there is no meter stats skip rendering
          if(!angular.isDefined(meter)){
            return;
          }
          containerBox.append('text')
          .attr({
            y: 105 + (i * 15),
            x: serviceTopologyConfig.instance.margin + (120 * j),
            opacity: 0
          })
          .text(`${m.label}: ${Math.round(meter.value)} ${meter.unit}`)
          .transition()
          .duration(serviceTopologyConfig.duration)
          .attr({
            opacity: 1
          });
        });
      });
    }

    const showInstanceStats = (container, instance) => {

      // NOTE this should be dinamically positioned
      // base on the number of element present
      const statsContainer = container.append('g')
        .attr({
          transform: `translate(200, -120)`,
          class: 'stats-container'
        });


      statsContainer.append('line')
        .attr({
          x1: -160,
          y1: 120,
          x2: 0,
          y2: 50,
          stroke: 'black',
          opacity: 0
        })
        .transition()
        .duration(serviceTopologyConfig.duration)
        .attr({
          opacity: 1
        })

      // NOTE rect should be dinamically sized base on the presence of a container
      let statsHeight = 110;
      let statsWidth = 250;

      if (instance.container){
        statsHeight += serviceTopologyConfig.container.height + (serviceTopologyConfig.container.margin * 2)
      }

      statsContainer.append('rect')
        .attr({
          width: statsWidth,
          height: statsHeight,
          opacity: 0
        })
        .transition()
        .duration(serviceTopologyConfig.duration)
        .attr({
          opacity: 1
        });

      // add instance info
      statsContainer.append('text')
        .attr({
          y: 15,
          x: serviceTopologyConfig.instance.margin,
          class: 'name',
          opacity: 0
        })
        .text(instance.humanReadableName)
        .transition()
        .duration(serviceTopologyConfig.duration)
        .attr({
          opacity: 1
        })

      statsContainer.append('text')
        .attr({
          y: 30,
          x: serviceTopologyConfig.instance.margin,
          class: 'ip',
          opacity: 0
        })
        .text(instance.ip)
        .transition()
        .duration(serviceTopologyConfig.duration)
        .attr({
          opacity: 1
        })

      // add stats
      const interestingMeters = ['memory', 'memory.usage', 'cpu', 'vcpus'];

      interestingMeters.forEach((m, i) => {
        const meter = lodash.find(instance.stats, {meter: m});
        statsContainer.append('text')
        .attr({
          y: 55 + (i * 15),
          x: serviceTopologyConfig.instance.margin,
          opacity: 0
        })
        .text(`${meter.description}: ${Math.round(meter.value)} ${meter.unit}`)
        .transition()
        .duration(serviceTopologyConfig.duration)
        .attr({
          opacity: 1
        });
      });

      if(instance.container){
        // draw container
        drawContainer(statsContainer, instance.container);
      }

    };

    this.drawInstances = (container, instances) => {
      
      // TODO check for stats field in instance and draw popup

      let {width, height} = container.node().getBoundingClientRect();

      let elements = container.selectAll('.instances')
      .data(instances, d => angular.isString(d.d3Id) ? d.d3Id : d.d3Id = `instance-${++instanceId}`)

      var instanceContainer = elements.enter().append('g');

      instanceContainer
      .attr({
        transform: `translate(${width / 2}, ${ height / 2})`,
        class: d => `instance ${d.selected ? 'active' : ''} ${getInstanceStatusColor(d)}`,
      })
      .transition()
      .duration(serviceTopologyConfig.duration)
      .attr({
        transform: (d, i) => `translate(${RackHelper.getInstancePosition(i)})`
      });

      instanceContainer.append('rect')
      .attr({
        width: 0,
        height: 0
      })
      .transition()
      .duration(serviceTopologyConfig.duration)
      .attr({
        width: serviceTopologyConfig.instance.width,
        height: serviceTopologyConfig.instance.height
      });

      instanceContainer.append('text')
      .attr({
        'text-anchor': 'middle',
        y: 23, //FIXME
        x: 40, //FIXME
        opacity: 0
      })
      .text(d => formatInstanceName(d.humanReadableName))
      .transition()
      .duration(serviceTopologyConfig.duration)
      .attr({
        opacity: 1
      });

      // if stats are attached and instance is active,
      // draw stats
      instanceContainer.each(function(instance, i){

        const container = d3.select(this);

        if(angular.isDefined(instance.stats) && instance.selected){
          showInstanceStats(container, instance, i);
        }
      });

      instanceContainer
      .on('click', function(d){
        console.log(`Draw vignette with stats for instance: ${d.name}`);
      });
    };

    this.addPhisical = (nodes) => {

      nodes.select('rect').remove();
      nodes.select('text').remove();

      nodes.append('rect')
      .attr(serviceTopologyConfig.square);

      nodes.append('text')
      .attr({
        'text-anchor': 'middle',
        y: serviceTopologyConfig.square.y - 10
      })
      .text(d => {
        return d.name || d.humanReadableName
      });
    }

    this.addDevice = (nodes) => {
      nodes.append('circle')
      .attr(serviceTopologyConfig.circle);

      nodes.append('text')
      .attr({
        'text-anchor': 'end',
        x: - serviceTopologyConfig.circle.r - 10,
        y: serviceTopologyConfig.circle.r / 2
      })
      .text(d => d.name || d.mac); 
    }
  });
})();
