
/*
 * Copyright 2017-present Open Networking Foundation

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


(function () {
  'use strict';

  angular.module('xos.serviceGrid')
  .service('Graph', function($q, Tenants, Services, Subscribers){

    let tenancyGraph = new graphlib.Graph();
    let cached = false;

    const buildGraph = () => {

      let deferred = $q.defer();

      $q.all([
        Tenants.query().$promise,
        Services.query().$promise,
        Subscribers.query().$promise
      ])
      .then((res) => {
        let [tenants, services, subscribers] = res;
        // adding service nodes
        services.forEach(s => tenancyGraph.setNode(s.id, angular.extend(s, {type: 'service'})));


        // coarse tenant
        tenants.filter(t => t.subscriber_service && t.provider_service)
          .forEach(t => tenancyGraph.setEdge(t.subscriber_service, t.provider_service, t, t.name));

        // fine grain tenant
        // adding subscribers as nodes (to build fine grain graph)
        // subscribers.forEach(s => tenancyGraph.setNode(`sub-${s.id}`, angular.extend(s, {type: 'subscriber'})));
        // TODO
        // - Find tenant that start from a subscriber
        // - Follow the chain: from the first tenant follow where subscriber_tenant = tenant_id untill we cannot find any more tenant
        // tenants.filter(t => t.subscriber_root && t.provider_service)
        // .forEach(t => tenancyGraph.setEdge(`sub-${t.subscriber_root}`, t.provider_service, t, t.name));
        
        deferred.resolve(tenancyGraph);
      });

      return deferred.promise;
    };

    this.getGraph = () => {
      let deferred = $q.defer();

      if(cached){
        deferred.resolve(tenancyGraph);
      }
      else {
        buildGraph()
        .then((res) => {
          cached = true;
          deferred.resolve(res);
        })
        .catch(console.log);
      }

      return {$promise: deferred.promise};
    };

  })
  .directive('serviceGraph', function(){
    return {
      restrict: 'E',
      scope: {},
      bindToController: true,
      controllerAs: 'vm',
      templateUrl: 'templates/service-graph.tpl.html',
      controller: function($scope, $element, GraphService, Graph, ToscaEncoder){

        let svg;
        let el = $element[0];
        let node, nodes;
        let link, links;
        const _this = this;

        this.panelConfig = {
          position: 'right'
        };

        // find position for link labels
        const xpos = (source, target) => {
          if (target.x > source.x) {
            return (source.x + (target.x - source.x)/2); }
          else {
            return (target.x + (source.x - target.x)/2); }
        }

        const ypos = (source, target) => {
          if (target.y > source.y) {
            return Math.round(source.y + (target.y - source.y)/2);
          }
          else {
            return Math.round(target.y + (source.y - target.y)/2); }
        }

        // animate node and links in the correct place
        const tick = () => {
          node
            .attr('cx', d => d.x)
            .attr('cy', d => d.y)
            .attr({
              transform: d => `translate(${d.x}, ${d.y})`
            });
          
          svg.selectAll('.link')
            .attr('x1', d => d.source.x)
            .attr('y1', d => d.source.y)
            .attr('x2', d => getTargetNodeCircumferencePoint(d)[0])
            .attr('y2', d => getTargetNodeCircumferencePoint(d)[1]);

          svg.selectAll('.link-text')
            .attr('x', d => xpos(d.source, {x: getTargetNodeCircumferencePoint(d)[0], y: getTargetNodeCircumferencePoint(d)[1]}))
            .attr('y', d => ypos(d.source, {x: getTargetNodeCircumferencePoint(d)[0], y: getTargetNodeCircumferencePoint(d)[1]}))
            .attr('transform', d => {
              let x = xpos(d.source, {x: getTargetNodeCircumferencePoint(d)[0], y: getTargetNodeCircumferencePoint(d)[1]});
              let y = ypos(d.source, {x: getTargetNodeCircumferencePoint(d)[0], y: getTargetNodeCircumferencePoint(d)[1]});
              return `rotate(-30, ${x}, ${y})`;
            });
        };

        var chainCount = 1;
        var spareCount = 1;

        const getNodePosition = (n, graph, chainElements) => {
          let node =  graph.node(n);
          const step = el.clientWidth / (chainElements + 1);

          if(graph.nodeEdges(n).length > 0){
            let pos = {
              y: el.clientHeight / 4,
              x: step * chainCount,
              fixed: true
            };
            angular.extend(node, pos);
            chainCount = chainCount + 1;
          }
          else {
            let pos = {
              y: (el.clientHeight / 2) + (el.clientHeight / 4),
              x: (step + step / 2) * spareCount,
              fixed: true
            };
            angular.extend(node, pos);
            spareCount = spareCount + 1;
          }
          return node;
        };

        Graph.getGraph().$promise
        .then((graph) => {

          // build links
          links = graph.edges().map(e => {
            return {
              source: graph.node(e.v),
              target: graph.node(e.w),
              tenant: graph.edge(e)
            }
          });
          
          // check how many nodes are connected
          // let longerGraph = graphlib.alg.components(graph).filter(g => g.length > 1);
          const longerGraph = graphlib.alg.components(graph).reduce(function (a, b) { return a.length > b.length ? a : b; }).length;

          nodes = graph.nodes().reverse().map(n => getNodePosition(n, graph, longerGraph));

          handleSvg(el);
          defineArrows();

          var force = d3.layout.force()
            .nodes(nodes)
            .links(links)
            .charge(-1060)
            .gravity(0.1)
            .linkDistance(200)
            .size([el.clientWidth, el.clientHeight])
            .on('tick', tick)
            .start();

          link = svg.selectAll('.link-container')
            .data(links).enter().insert('g')
            .attr('class', 'link-container');

          link.insert('line')
            .attr('class', 'link')
            .attr('marker-end', 'url(#arrow)');

          var linkText = svg.selectAll('.link-container')
            .data(force.links())
            .insert('text')
            .attr({
              class: 'link-text',
              'text-anchor': 'start'
            })
            .text(d => `${d.tenant.humanReadableName}`)

          node = svg.selectAll('.node')
            .data(nodes)
            .enter().append('g')
            .call(force.drag)
            .on('mousedown', function(d) {
              $scope.$apply(() => {
                if(d.name === 'XOS'){
                  return;
                }
                _this.panelShow = true;
                let status = parseInt(d.backend_status.match(/^[0-9]/)[0]);
                console.log(status);
                switch(status){
                  case 0:
                    d.icon = 'time';
                    break;
                  case 1:
                    d.icon = 'ok';
                    break;
                  case 2:
                    d.icon = 'remove';
                    break;
                }
                _this.selectedNode = d;
              });
              d3.event.stopPropagation();
            });

          node.append('circle')
            .attr({
              class: d => `node ${d.type || ''}`,
              r: 10
            });

          node.append('text')
            .attr({
              'text-anchor': 'middle',
              'alignment-baseline': 'middle'
            })
            .text(d => d.humanReadableName || d.name);

          // scale the node to fit the contained text
          node.select('circle')
            .attr({
              r: function(d){
                const parent = d3.select(this).node().parentNode;
                const sib = d3.select(parent).select('text').node().getBBox();
                const radius = (sib.width / 2) + 10;

                // add radius as node attribute
                d.nodeWidth = radius * 2;
                return radius;
              }
            })

        });

        const handleSvg = (el) => {
          d3.select(el).select('svg').remove();

          svg = d3.select(el)
          .append('svg')
          .style('width', `${el.clientWidth}px`)
          .style('height', `${el.clientHeight}px`);
        };

        const defineArrows = () => {
          svg.append('svg:defs').selectAll('marker')
          .data(['arrow'])      // Different link/path types can be defined here
          .enter().append('svg:marker')    // This section adds in the arrows
          .attr('id', String)
          .attr('viewBox', '0 -5 10 10')
          .attr('refX', 10)
          .attr('refY', 0)
          .attr('markerWidth', 6)
          .attr('markerHeight', 6)
          .attr('orient', 'auto')
          .attr('class', 'link-arrow')
          .append('svg:path')
          .attr('d', 'M0,-5L10,0L0,5');
        };

        const getTargetNodeCircumferencePoint = d => {
          const radius = d.target.nodeWidth / 2; // nodeWidth is just a custom attribute I calculate during the creation of the nodes depending on the node width
          const dx = d.target.x - d.source.x;
          const dy = d.target.y - d.source.y;
          const gamma = Math.atan2(dy, dx); // Math.atan2 returns the angle in the correct quadrant as opposed to Math.atan

          const tx = d.target.x - (Math.cos(gamma) * radius);
          const ty = d.target.y - (Math.sin(gamma) * radius);

          return [tx, ty];
        };

        this.exportToTosca = (service) => {
          ToscaEncoder.serviceToTosca(service);
        }
      }
    };
  })
})();