[CORD-814] Building nodes and links for coarse tenancy graph

Change-Id: I85769dc4c8d7f7714fa4b59f052d0073e7b32ec5
diff --git a/src/app/service-graph/services/graph.store.ts b/src/app/service-graph/services/graph.store.ts
index e892b99..f9d4d15 100644
--- a/src/app/service-graph/services/graph.store.ts
+++ b/src/app/service-graph/services/graph.store.ts
@@ -1,9 +1,14 @@
+import * as _ from 'lodash';
 import {Observable, BehaviorSubject} from 'rxjs';
 import {IXosModelStoreService} from '../../datasources/stores/model.store';
-import {IXosServiceGraph, IXosServiceModel, IXosTenantModel} from '../interfaces';
+import {
+  IXosServiceGraph, IXosServiceModel, IXosTenantModel, IXosCoarseGraphData,
+  IXosServiceGraphNode, IXosServiceGraphLink
+} from '../interfaces';
 import {IXosDebouncer} from '../../core/services/helpers/debounce.helper';
 export interface IXosServiceGraphStore {
   get(): Observable<IXosServiceGraph>;
+  getCoarse(): Observable<IXosServiceGraph>;
 }
 
 export class XosServiceGraphStore implements IXosServiceGraphStore {
@@ -12,7 +17,16 @@
     'XosModelStore',
     'XosDebouncer'
   ];
-  private d3Graph = new BehaviorSubject({});
+
+  // graph data store
+  private graphData: BehaviorSubject<IXosCoarseGraphData> = new BehaviorSubject({
+    services: [],
+    tenants: []
+  });
+
+  // reprentations of the graph as D3 requires
+  private d3CoarseGraph = new BehaviorSubject({});
+  private d3FineGrainedGraph = new BehaviorSubject({});
 
   // storing locally reference to the data model
   private services;
@@ -31,12 +45,15 @@
     private XosDebouncer: IXosDebouncer
   ) {
 
+    this.$log.info(`[XosServiceGraphStore] Setup`);
+
     // we want to have a quiet period of 500ms from the last event before doing anything
-    this.handleData = this.XosDebouncer.debounce(this._handleData, 500, false);
+    this.handleData = this.XosDebouncer.debounce(this._handleData, 500, this, false);
 
     this.ServiceObservable = this.XosModelStore.query('Service', '/core/services');
-    this.TenantObservable = this.XosModelStore.query('Service', '/core/tenants');
+    this.TenantObservable = this.XosModelStore.query('Tenant', '/core/tenants');
 
+    // observe models and populate graphData
     this.ServiceObservable
       .subscribe(
         (res) => {
@@ -47,7 +64,7 @@
         }
       );
 
-    this.ServiceObservable
+    this.TenantObservable
       .subscribe(
         (res) => {
           this.combineData(res, 'tenants');
@@ -56,10 +73,30 @@
           this.$log.error(err);
         }
       );
+
+    // observe graphData and build Coarse or FineGrained graphs (based on who's subscribed)
+    this.graphData
+      .subscribe(
+        (res: IXosCoarseGraphData) => {
+          if (this.d3CoarseGraph.observers.length > 0) {
+            this.graphDataToCoarseGraph(res);
+          }
+          if (this.d3FineGrainedGraph.observers.length > 0) {
+            // TODO graphDataToFineGrainedGraph
+          }
+        },
+        (err) => {
+          this.$log.error(`[XosServiceGraphStore] graphData Observable: `, err);
+        }
+      );
   }
 
   public get() {
-    return this.d3Graph.asObservable();
+    return this.d3FineGrainedGraph.asObservable();
+  }
+
+  public getCoarse() {
+    return this.d3CoarseGraph.asObservable();
   }
 
   private combineData(data: any, type: 'services'|'tenants') {
@@ -75,7 +112,40 @@
   }
 
   private _handleData(services: IXosServiceModel[], tenants: IXosTenantModel[]) {
-    this.$log.log(`XosServiceGraphStore`, services, tenants);
+    this.graphData.next({
+      services: this.services,
+      tenants: this.tenants
+    });
+  }
+
+  private graphDataToCoarseGraph(data: IXosCoarseGraphData) {
+
+    const links: IXosServiceGraphLink[] = _.chain(data.tenants)
+      .filter((t: IXosTenantModel) => t.kind === 'coarse')
+      .map((t: IXosTenantModel) => {
+        return {
+          id: t.id,
+          source: t.provider_service_id,
+          target: t.subscriber_service_id,
+          model: t
+        };
+      })
+      .value();
+
+    // NOTE show all services anyway or find only the node that have links pointing to it
+    const nodes: IXosServiceGraphNode[] = _.map(data.services, (s: IXosServiceModel) => {
+      return {
+        id: s.id,
+        label: s.name,
+        model: s
+      };
+    });
+
+    // TODO call next on this.d3CoarseGraph
+    this.d3CoarseGraph.next({
+      nodes: nodes,
+      links: links
+    });
   }
 
 }