/**
 * © OpenCORD
 *
 * Visit http://guide.xosproject.org/devguide/addview/ for more information
 *
 * Created by teone on 10/20/16.
 */

(function () {
  'use strict';
  angular.module('xos.globalXos')
  .service('Controllers', function($resource){
    return $resource('/api/core/controllers/:id', {id: '@id'});
  })
  .service('GXOS', function($q, $resource, _, LXOS){
    this.attachXosToItem = (items, target = LXOS) => {
      return _.map(items, (lxos, i) => {
        let currentXos = target[i];
        return _.map(lxos, (item) => {
          item.xos = currentXos;
          return item;
        });
      })
    };

    this.buildQueryEndpoint = (baseUrl, target = LXOS) => {
      return () => {
        const d = $q.defer();

        // store generated $resource for each L-XOS
        let r = [];

        let p = [];
        _.forEach(target, (xos, i) => {
          let resource = $resource(`${xos.auth_url}${baseUrl}`, {id: '@id'}, {
            query: {
              isArray: true,
              headers: {
                Authorization: `Basic ${btoa(xos.admin_user + ':' + xos.admin_password)}`
              }
            }
          });
          r.push(resource);
          p.push(r[i].query().$promise);
        });

        $q.all(p)
        .then(res => {
          res = this.attachXosToItem(res, target);
          d.resolve(_.flatten(res));
        })
        .catch(d.reject);

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

    // TODO evaluate
    this.buildLocalResource = (baseUrl, xos) => {
      const headers = {
        Authorization: `Basic ${btoa(xos.admin_user + ':' + xos.admin_password)}`
      };
      const resource = $resource(`${xos.auth_url}${baseUrl}`, {id: '@id'}, {
        query: {
          isArray: true,
          headers: headers
        }
      });
      return resource;
    }
  })
  .service('LocalAuth', function ($q, $http, _, LXOS) {
    const baseUrl = `api/utility/login/`;
    this.login = () => {
      const d = $q.defer();

      let p = [];
      _.forEach(LXOS, (xos, i) => {
        let loginRequest = $http.post(`${xos.auth_url}${baseUrl}`, {username: xos.admin_user, password: xos.admin_password});
        p.push(loginRequest);
      });

      $q.all(p)
      .then(auths => {
        _.forEach(auths, (auth, i) => {
          LXOS[i].xoscsrftoken = auth.data.xoscsrftoken;
          LXOS[i].xossessionid = auth.data.xossessionid;
          LXOS[i].user = JSON.parse(auth.data.user);
        });
        d.resolve();
      })
      .catch(e => {
        d.reject(e);
      });

      return d.promise;
    }
  })
  .service('LocalSlices', function(GXOS){
    const baseUrl = `api/utility/slicesplus/`;

    // TODO build a global resource
    this.queryFromAll = (targets) => {
      return GXOS.buildQueryEndpoint(baseUrl, targets)();
    };
  })
  .service('LocalUsers', function(GXOS){
    const baseUrl = `api/core/users/`;

    // TODO build a global resource
    this.queryFromAll = GXOS.buildQueryEndpoint(baseUrl);
  })
  .service('LocalInstances', function($q, $http, GXOS, LocalDeployments, LocalImages, LocalFlavor, LocalNode){
    const baseUrl = `api/core/instances/`;

    // NOTE Evaluate to dinamically create a resource targeted to a L-XOS

    this.queryFromAll = (targets) => {
      return GXOS.buildQueryEndpoint(baseUrl, targets)();
    };
    this.createOnLocal = (instance) => {
      const d = $q.defer();
      const xos = instance.xos;
      delete instance.xos;
      $http.post(`${xos.auth_url}${baseUrl}`, instance, {
        headers: {
          Authorization: `Basic ${btoa(xos.admin_user + ':' + xos.admin_password)}`
        }
      })
      .then((inst) => {
        d.resolve(inst);
      })
      .catch(e => {
        d.reject(e);
      });

      return d.promise;
    };

    this.getFromLocal = (xos, params) => {
      const d = $q.defer();
      $http.get(`${xos.auth_url}${baseUrl}`, {
        params: params,
        headers: {
          Authorization: `Basic ${btoa(xos.admin_user + ':' + xos.admin_password)}`
        }
      })
        .then((inst) => {
          d.resolve(inst.data);
        })
        .catch(e => {
          d.reject(e);
        });

      return d.promise;
    };

    this.getLocalInfo = (xos) => {
      const d = $q.defer();
      $q.all([
        LocalDeployments.queryFromLocal(xos),
        LocalImages.queryFromLocal(xos),
        LocalFlavor.queryFromLocal(xos),
        LocalNode.queryFromLocal(xos)
      ])
        .then((res) => {
          res = _.map(res, collection => {
            return _.map(collection, item => {
              return {id: item.id, label: item.name}
            });
          });
          d.resolve(res);
        })
        .catch(d.reject);
      return d.promise;
    };

  })
  .service('LocalDeployments', function($q, $http){

    const baseUrl = `api/core/deployments/`;

    this.queryFromLocal = (xos) => {
      const d = $q.defer();

      $http.get(`${xos.auth_url}${baseUrl}`, {
        headers: {
          Authorization: `Basic ${btoa(xos.admin_user + ':' + xos.admin_password)}`
        }
      })
      .then((res) => {
        d.resolve(res.data);
      })
      .catch(e => {
        d.reject(e);
      });

      return d.promise;
    }
  })
  .service('LocalImages', function($q, $http){

    const baseUrl = `api/core/images/`;

    this.queryFromLocal = (xos) => {
      const d = $q.defer();

      $http.get(`${xos.auth_url}${baseUrl}`, {
        headers: {
          Authorization: `Basic ${btoa(xos.admin_user + ':' + xos.admin_password)}`
        }
      })
      .then((res) => {
        d.resolve(res.data);
      })
      .catch(e => {
        d.reject(e);
      });

      return d.promise;
    }
  })
  .service('LocalFlavor', function($q, $http){

    const baseUrl = `api/core/flavors/`;

    this.queryFromLocal = (xos) => {
      const d = $q.defer();

      $http.get(`${xos.auth_url}${baseUrl}`, {
        headers: {
          Authorization: `Basic ${btoa(xos.admin_user + ':' + xos.admin_password)}`
        }
      })
        .then((res) => {
          d.resolve(res.data);
        })
        .catch(e => {
          d.reject(e);
        });

      return d.promise;
    }
  })
  .service('LocalNode', function($q, $http){

    const baseUrl = `api/core/nodes/`;

    this.queryFromLocal = (xos) => {
      const d = $q.defer();

      $http.get(`${xos.auth_url}${baseUrl}`, {
        headers: {
          Authorization: `Basic ${btoa(xos.admin_user + ':' + xos.admin_password)}`
        }
      })
        .then((res) => {
          d.resolve(res.data);
        })
        .catch(e => {
          d.reject(e);
        });

      return d.promise;
    }
  });
})();

