(function () {
  'use strict';

  angular.module('xos.serviceTopology')
  .service('Services', function($resource){
    return $resource('/xos/services/:id', {id: '@id'});
  })
  .service('Tenant', function($resource){
    return $resource('/xos/tenants', {id: '@id'}, {
      queryVsgInstances: {
        method: 'GET',
        isArray: true,
        interceptor: {
          response: (res) => {

            // NOTE
            // Note that VCPETenant is now VSGTenant.

            let instances = [];

            angular.forEach(res.data, (tenant) => {
              let info = JSON.parse(tenant.service_specific_attribute);
              if(info && info.instance_id){
                instances.push(info.instance_id);
              }
            });

            return instances;
          }
        }
      },
      getSubscriberTag: {
        method: 'GET',
        isArray: true,
        interceptor: {
          response: (res) => {
            // NOTE we should receive only one vOLT tenant here
            return JSON.parse(res.data[0].service_specific_attribute);
          }
        }
      }
    });
  })
  .service('Ceilometer', function($http, $q, Instances) {

    /**
    * Get stats for a single instance
    */
    this.getInstanceStats = (instanceUuid) => {
      let deferred = $q.defer();

      $http.get('/xoslib/meterstatistics', {params:{resource: instanceUuid}})
      .then((res) => {
        deferred.resolve(res.data);
      })
      .catch((e) => {
        deferred.reject(e);
      })

      return deferred.promise;
    };

    /**
    * Collect stats for an array of instances
    */
    this.getInstancesStats = (instances) => {
      let deferred = $q.defer();
      let instancePromises = [];
      let instanceList = [];

      // retrieve instance details
      instances.forEach((instanceId) => {
        instancePromises.push(Instances.get({id: instanceId}).$promise);
      });

      // get all instance data
      $q.all(instancePromises)
      .then((_instanceList) => {
        instanceList = _instanceList;
        let promises = [];
        // foreach instance query stats
        instanceList.forEach((instance) => {
          promises.push(this.getInstanceStats(instance.instance_uuid));
        });
        return $q.all(promises);
      })
      .then(stats => {
        // augment instance with stats information
        instanceList.map((instance, i) => {
          instance.stats = stats[i];
        });
        deferred.resolve(instanceList);
      })
      .catch(deferred.reject);

      return deferred.promise;
    };
  })
  .service('Slice', function($resource){
    return $resource('/xos/slices', {id: '@id'});
  })
  .service('Instances', function($resource){
    return $resource('/xos/instances/:id', {id: '@id'});
  })
  .service('Node', function($resource, $q, Instances){
    return $resource('/xos/nodes', {id: '@id'}, {
      queryWithInstances: {
        method: 'GET',
        isArray: true,
        interceptor: {
          response: function(res){

            // TODO update the API to include instances in nodes
            // http://stackoverflow.com/questions/14573102/how-do-i-include-related-model-fields-using-django-rest-framework

            const deferred = $q.defer();

            let requests = [];

            angular.forEach(res.data, (node) => {
              requests.push(Instances.query({node: node.id}).$promise);
            })

            $q.all(requests)
            .then((list) => {
              res.data.map((node, i) => {
                node.instances = list[i];
                return node;
              });
              deferred.resolve(res.data);
            })

            return deferred.promise;
          }
        }
      }
    });
  })
  .service('Subscribers', function($resource, $q, SubscriberDevice){
    return $resource('/xos/subscribers/:id', {id: '@id'}, {
      queryWithDevices: {
        method: 'GET',
        isArray: true,
        interceptor: {
          response: function(res){

            /**
            * For each subscriber retrieve devices and append them
            */

            let deferred = $q.defer();

            let requests = [];

            angular.forEach(res.data, (subscriber) => {
              requests.push(SubscriberDevice.query({id: subscriber.id}).$promise);
            })

            $q.all(requests)
            .then((list) => {

              // adding devices

              res.data.map((subscriber, i) => {
                subscriber.devices = list[i];
                subscriber.type = 'subscriber';

                subscriber.devices.map(d => d.type = 'device')

                return subscriber;
              });

              // faking to have 2 subscriber
              // res.data.push(angular.copy(res.data[0]));

              deferred.resolve(res.data);
            })

            return deferred.promise;
          }
        }
      },
      getWithDevices: {
        method: 'GET',
        isArray: false,
        interceptor: {
          response: (res) => {
            let d = $q.defer();

            SubscriberDevice.query({id: res.data.id}).$promise
            .then(devices => {
              devices.map(d => d.type = 'device');
              res.data.devices = devices;
              res.data.type = 'subscriber';
              d.resolve(res.data);
            })
            .catch(err => {
              d.reject(err);
            });

            return d.promise;
          }
        }
      }
    });
  })
  .service('SubscriberDevice', function($resource){
    return $resource('/xoslib/rs/subscriber/:id/users/', {id: '@id'});
  })
  .service('ServiceRelation', function($q, lodash, Services, Tenant, Slice, Instances){

    // count the mas depth of an object
    const depthOf = (obj) => {
      var depth = 0;
      if (obj.children) {
        obj.children.forEach(function (d) {
          var tmpDepth = depthOf(d);
          if (tmpDepth > depth) {
            depth = tmpDepth
          }
        })
      }
      return 1 + depth
    };

    // find all the relation defined for a given root
    const findLevelRelation = (tenants, rootId) => {
      return lodash.filter(tenants, service => {
        return service.subscriber_service === rootId;
      });
    };

    const findSpecificInformation = (tenants, rootId) => {
      var tenants = lodash.filter(tenants, service => {
        return service.provider_service === rootId && service.subscriber_tenant;
      });

      var info;

      tenants.forEach((tenant) => {
        if(tenant.service_specific_attribute){
          info = JSON.parse(tenant.service_specific_attribute);
        }
      });

      return info;
    };

    // find all the service defined by a given array of relations
    const findLevelServices = (relations, services) => {
      const levelServices = [];
      lodash.forEach(relations, (tenant) => {
        var service = lodash.find(services, {id: tenant.provider_service});
        levelServices.push(service);
      });
      return levelServices;
    };

    const buildLevel = (tenants, services, rootService, rootTenant, parentName = null) => {

      // build an array of unlinked services
      // these are the services that should still placed in the tree
      var unlinkedServices = lodash.difference(services, [rootService]);

      // find all relations relative to this rootElement
      const levelRelation = findLevelRelation(tenants, rootService.id);

      // find all items related to rootElement
      const levelServices = findLevelServices(levelRelation, services);

      // remove this item from the list (performance
      unlinkedServices = lodash.difference(unlinkedServices, levelServices);

      rootService.service_specific_attribute = findSpecificInformation(tenants, rootService.id);

      const tree = {
        name: rootService.humanReadableName,
        parent: parentName,
        type: 'service',
        service: rootService,
        tenant: rootTenant,
        children: []
      };

      lodash.forEach(levelServices, (service) => {
        let tenant = lodash.find(tenants, {subscriber_tenant: rootTenant.id, provider_service: service.id});
        tree.children.push(buildLevel(tenants, unlinkedServices, service, tenant, rootService.humanReadableName));
      });

      // if it is the last element append internet
      if(tree.children.length === 0){
        tree.children.push({
          name: 'Router',
          type: 'router',
          children: []
        });
      }

      return tree;
    };

    const buildSubscriberServiceTree = (services, tenants, subscriber = {id: 1, name: 'fakeSubs'}) => {

      // find the root service
      // it is the one attached to subsriber_root
      // as now we have only one root so this can work
      const rootTenant = lodash.find(tenants, {subscriber_root: subscriber.id});
      const rootService = lodash.find(services, {id: rootTenant.provider_service});

      const serviceTree = buildLevel(tenants, services, rootService, rootTenant);

      return {
        name: subscriber.name,
        parent: null,
        type: 'subscriber',
        children: [serviceTree]
      };

    };

    // applying domain knowledge to build the global service tree
    const buildServiceTree = (services, tenants) => {

      // TODO refactor
      const buildChild = (services, tenants, currentService) => {

        const response = {
          type: 'service',
          name: currentService.humanReadableName,
          service: currentService
        };

        let tenant = lodash.find(tenants, {subscriber_service: currentService.id});
        if(tenant){
          let next = lodash.find(services, {id: tenant.provider_service});
          response.children = [buildChild(services, tenants, next)];
        }
        else {
          response.children = [
            {
              name: 'Router',
              type: 'router',
              children: []
            }
          ]
        }
        delete currentService.id; // conflict with d3
        return response;
      }
      let baseService = lodash.find(services, {id: 3});

      const baseData = {
        name: 'Subscriber',
        type: 'subscriber',
        parent: null,
        children: [buildChild(services, tenants, baseService)]
      };
      return baseData;
    };

    const getBySubscriber = (subscriber) => {
      var deferred = $q.defer();
      var services, tenants;
      Services.query().$promise
      .then((res) => {
        services = res;
        return Tenant.query().$promise;
      })
      .then((res) => {
        tenants = res;
        deferred.resolve(buildSubscriberServiceTree(services, tenants, subscriber));
      })
      .catch((e) => {
        throw new Error(e);
      });

      return deferred.promise;
    };

    const get = () => {
      var deferred = $q.defer();
      var services, tenants;
      Services.query().$promise
      .then((res) => {
        services = res;
        return Tenant.query({kind: 'coarse'}).$promise;
      })
      .then((res) => {
        tenants = res;
        deferred.resolve(buildServiceTree(services, tenants));
      })
      .catch((e) => {
        throw new Error(e);
      });

      return deferred.promise;
    }

    // export APIs
    return {
      get: get,
      buildServiceTree: buildServiceTree,
      getBySubscriber: getBySubscriber,
      buildLevel: buildLevel,
      buildSubscriberServiceTree: buildSubscriberServiceTree,
      findLevelRelation: findLevelRelation,
      findLevelServices: findLevelServices,
      depthOf: depthOf,
      findSpecificInformation: findSpecificInformation
    }
  });

}());