/**
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you 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.
 */
'use strict';

AppServices.Services.factory('ug', function (configuration, $rootScope,utility, $q, $http, $resource, $log,$location) {

  var requestTimes = [],
    running = false,
    currentRequests = {};

  function reportError(data,config){
      console.error(data)
  };
  var getAccessToken = function(){
    return sessionStorage.getItem('accessToken');
  };

  return {
    get:function(prop,isObject){
      return isObject ? this.client().getObject(prop) : this.client().get(prop);
    },
    set:function(prop,value){
      this.client().set(prop,value);

    },
    getUrls: function(qs){
      var host = $location.host();
      var BASE_URL = '';
      var DATA_URL = '';
      var use_sso = false;
      switch (true) {
        case host === 'usergrid.dev':
          //development
          DATA_URL = 'https://api.usergrid.com';
          break;
        default :
          DATA_URL = Usergrid.overrideUrl;
          break;
      }
      //override with querystring
      DATA_URL = qs['api_url'] || DATA_URL;
      DATA_URL = DATA_URL.lastIndexOf('/') === DATA_URL.length - 1 ? DATA_URL.substring(0,DATA_URL.length-1) : DATA_URL;
      return {
        DATA_URL: DATA_URL,
        LOGIN_URL: BASE_URL + '/accounts/sign_in',
        PROFILE_URL: BASE_URL + '/accounts/my_account',
        LOGOUT_URL: BASE_URL + '/accounts/sign_out',
        apiUrl: DATA_URL,
        use_sso:use_sso
      };
    },
    orgLogin:function(username,password){
      var self = this;
      this.client().set('email', username);
      this.client().set('token', null);
      this.client().orgLogin(username,password,function(err, data, user, organizations, applications){
        if(err){
          $rootScope.$broadcast('loginFailed', err,data);
        }else{
          self.initializeCurrentUser(function () {
            $rootScope.$broadcast('loginSuccesful', user, organizations, applications);
          });
        }
      });
    },
    checkAuthentication:function(force){
      var ug = this;
      var client = ug.client();

      var initialize = function () {
            ug.initializeCurrentUser(function () {
              $rootScope.userEmail = client.get('email');
              $rootScope.organizations = client.getObject('organizations');
              $rootScope.applications = client.getObject('applications');
              $rootScope.currentOrg = client.get('orgName');
              $rootScope.currentApp = client.get('appName');
              var size = 0, key;
              for (key in  $rootScope.applications) {
                if ($rootScope.applications.hasOwnProperty(key)) size++;
              }
              $rootScope.$broadcast('checkAuthentication-success', client.getObject('organizations'), client.getObject('applications'), client.get('orgName'), client.get('appName'), client.get('email'));
            });
          },
          isAuthenticated = function () {
            var authenticated = client.get('token') !== null && client.get('organizations') !== null;
            if (authenticated) {
              initialize();
            }
            return authenticated;
          };
      if(!isAuthenticated() || force){
        if(!client.get('token')){
          return $rootScope.$broadcast('checkAuthentication-error','no token',{},client.get('email'));
        }
        this.client().reAuthenticateLite(function(err){
          var missingData = err || ( !client.get('orgName') || !client.get('appName') || !client.getObject('organizations') || !client.getObject('applications'));
          var email  = client.get('email');
          if(err || missingData){
            $rootScope.$broadcast('checkAuthentication-error',err,missingData,email);
          }else{
            initialize();
          }
        });
      }
    },
    reAuthenticate:function(email,eventOveride){
      var ug = this;
      this.client().reAuthenticate(email,function(err, data, user, organizations, applications){
        if(!err){
          $rootScope.currentUser = user;
        }
        if(!err){
          $rootScope.userEmail = user.get('email');
          $rootScope.organizations = organizations;
          $rootScope.applications = applications;
          $rootScope.currentOrg = ug.get('orgName');
          $rootScope.currentApp = ug.get('appName');
          $rootScope.currentUser = user._data;
          $rootScope.currentUser.profileImg = utility.get_gravatar($rootScope.currentUser.email);
        }
        $rootScope.$broadcast((eventOveride || 'reAuthenticate')+'-' + (err ? 'error' : 'success'),err, data, user, organizations, applications);

      });
    },
    logoutCallback: function() {
      $rootScope.$broadcast('userNotAuthenticated');
    },
    logout:function(){
      $rootScope.activeUI = false;
      $rootScope.userEmail = 'user@apigee.com';
      $rootScope.organizations = {"noOrg":{name:"No Orgs Found"}};
      $rootScope.applications = {"noApp":{name:"No Apps Found"}};
      $rootScope.currentOrg = 'No Org Found';
      $rootScope.currentApp = 'No App Found';
      sessionStorage.setItem('accessToken', null);
      sessionStorage.setItem('userUUID', null);
      sessionStorage.setItem('userEmail', null);

      this.client().logout();
      this._client = null;
    },
    client: function(){
      var options = {
        buildCurl:true,
        logging:true
      };
      if(Usergrid.options && Usergrid.options.client){
        options.keys = Usergrid.options.client;
      }

      this._client = this._client || new Usergrid.Client(options,
          $rootScope.urls().DATA_URL
      );
      return this._client;
    },
    setClientProperty:function(key,value){
      this.client().set(key, value);
    },
    getTopCollections: function () {
      var options = {
        method:'GET',
        endpoint: ''
      }
      this.client().request(options, function (err, data) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error getting collections');
        } else {
          var collections = data.entities[0].metadata.collections;
          $rootScope.$broadcast('top-collections-received', collections);
        }
      });
    },
    createCollection: function (collectionName) {
      var collections = {};
      collections[collectionName] = {};
      var metadata = {
        metadata: {
          collections: collections
        }
      }
      var options = {
        method:'PUT',
        body: metadata,
        endpoint: ''
      }
      this.client().request(options, function (err, data) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error creating collection');
        } else {
          $rootScope.$broadcast('collection-created', collections);
        }
      });
    },
    getApplications: function () {
      this.client().getApplications(function (err, applications) {
        if (err) {
           applications && console.error(applications);
        }else{
          $rootScope.$broadcast('applications-received', applications);
        }
      });
    },
    getAdministrators: function () {
      this.client().getAdministrators(function (err, administrators) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error getting administrators');
        }
        var enabledAdmins = [];
        for(var i=0; i<administrators.length; i++){
          if(administrators[i].disabled === false){
            enabledAdmins.push(administrators[i]);
          }
        }
        $rootScope.$broadcast('administrators-received', enabledAdmins);
      });
    },
    createApplication: function (appName) {
      this.client().createApplication(appName, function (err, applications) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error creating application');
        }else{
          $rootScope.$broadcast('applications-created', applications,appName);
          $rootScope.$broadcast('applications-received', applications);
        }
      });
    },
    createAdministrator: function (adminName) {
      this.client().createAdministrator(adminName, function (err, administrators) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error creating administrator');
        }
        var enabledAdmins = [];
        for(var i=0; i<administrators.length; i++){
          if(administrators[i].disabled === false){
            enabledAdmins.push(administrators[i]);
          }
        }
        $rootScope.$broadcast('administrators-received', enabledAdmins);
      });
    },
    getFeed: function () {
      var options = {
        method:'GET',
        endpoint:'management/organizations/'+this.client().get('orgName')+'/feed',
        mQuery:true
      };
      this.client().request(options, function (err, data) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error getting feed');
        } else {
          var feedData = data.entities;
          var feed = [];
          var i=0;
          for (i=0; i < feedData.length; i++) {
            var date = (new Date(feedData[i].created)).toUTCString();

            var title = feedData[i].title;

            var n=title.indexOf(">");
            title = title.substring(n+1,title.length);

            n=title.indexOf(">");
            title = title.substring(n+1,title.length);

            if (feedData[i].actor) {
              title = feedData[i].actor.displayName + ' ' + title;
            }
            feed.push({date:date, title:title});
          }
          if (i === 0) {
            feed.push({date:"", title:"No Activities found."});
          }

          $rootScope.$broadcast('feed-received', feed);
        }
      });

    },
    createGroup: function (path, title) {
      var options = {
        path:path,
        title:title
      }
      var self = this;
      this.groupsCollection.addEntity(options, function(err){
        if (err) {
          $rootScope.$broadcast('groups-create-error', err);
        } else {
          $rootScope.$broadcast('groups-create-success', self.groupsCollection);
          $rootScope.$broadcast('groups-received', self.groupsCollection);
        }
      });
    },
    createRole: function (name, title) {
      var options = {
        name:name,
        title:title
          },
          self = this;
      this.rolesCollection.addEntity(options, function(err){
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error creating role');
        } else {
          $rootScope.$broadcast('roles-received', self.rolesCollection);
        }
      });
    },
    createUser: function (username, name, email, password){
      var options = {
        username:username,
        name:name,
        email:email,
        password:password
      }
      var self = this;
      this.usersCollection.addEntity(options, function(err, data){
        if (err) {
          if (typeof data === 'string') {
            $rootScope.$broadcast("alert", "error", "error: " + data);
          } else {
            $rootScope.$broadcast("alert", "error", "error creating user. the email address might already exist.");
          }
        } else {
          $rootScope.$broadcast('users-create-success', self.usersCollection);

          $rootScope.$broadcast('users-received', self.usersCollection);
        }
      });
    },
    getCollection: function (type, path, orderBy, query, limit) {
      var options = {
        type:path,
        qs:{}
      }
      if (query) {
        options.qs['ql'] = query;
      }

      //force order by 'created desc' if none exists
      if (options.qs.ql) {
        options.qs['ql'] = options.qs.ql + ' order by ' + (orderBy || 'created desc');
      } else {
        options.qs['ql'] = ' order by ' + (orderBy || 'created desc');
      }

      if (limit) {
        options.qs['limit'] = limit;
      }
      this.client().createCollection(options, function (err, collection, data) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error getting ' + collection._type + ': ' + data.error_description);
          $rootScope.$broadcast(type + '-error', collection);
        } else {
          $rootScope.$broadcast(type + '-received', collection);
        }
        //temporarily adding scope.apply to get working in prod, otherwise the events won't get broadcast
        //todo - we need an apply strategy for 3rd party ug calls!
        if(!$rootScope.$$phase) {
          $rootScope.$apply();
        }
      });
    },
    runDataQuery: function (queryPath, searchString, queryLimit) {
      this.getCollection('query', queryPath, null, searchString, queryLimit);
    },
    runDataPOSTQuery: function(queryPath, body) {
      var self = this;
      var options = {
        method:'POST',
        endpoint:queryPath,
        body:body
      };
      this.client().request(options, function (err, data) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error: ' + data.error_description);
          $rootScope.$broadcast('error-running-query',  data);
        } else {

          var queryPath = data.path;
          //remove preceeding slash
          queryPath = queryPath.replace(/^\//, ''); 
          self.getCollection('query', queryPath, null, 'order by modified DESC', null);

        }
      });
    },
    runDataPutQuery: function(queryPath, searchString, queryLimit, body) {
      var self = this;
      var options = {
        method:'PUT',
        endpoint:queryPath,
        body:body
      };

      if (searchString) {
        options.qs['ql'] = searchString;
      }
      if (queryLimit) {
        options.qs['queryLimit'] = queryLimit;
      }

      this.client().request(options, function (err, data) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error: ' + data.error_description);
        } else {

          var queryPath = data.path;
          self.getCollection('query', queryPath, null, 'order by modified DESC', null);

        }
      });
    },
    runDataDeleteQuery: function(queryPath, searchString, queryLimit) {
      var self = this;
      var options = {
        method:'DELETE',
        endpoint:queryPath
      };

      if (searchString) {
        options.qs['ql'] = searchString;
      }
      if (queryLimit) {
        options.qs['queryLimit'] = queryLimit;
      }

      this.client().request(options, function (err, data) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error: ' + data.error_description);
        } else {

          var queryPath = data.path;
          self.getCollection('query', queryPath, null, 'order by modified DESC', null);

        }
      });
    },
    getUsers: function () {
      this.getCollection('users','users','username');
      var self = this;
      $rootScope.$on("users-received",function(evt, users){
        self.usersCollection = users;
      })
    },
    getGroups: function () {
      this.getCollection('groups','groups','title');
      var self = this;
      $rootScope.$on('groups-received', function(event, roles) {
        self.groupsCollection = roles;
      });

     },
    getRoles: function () {
      this.getCollection('roles','roles','name');
      var self = this;
      $rootScope.$on('roles-received', function(event, roles) {
        self.rolesCollection = roles
      });
    },
    getNotifiers: function () {
      var query = '',
          limit = '100',
          self = this;
      this.getCollection('notifiers','notifiers','created', query, limit);
      $rootScope.$on('notifiers-received', function(event, notifiers) {
        self.notifiersCollection = notifiers;
      });
    },
    getNotificationHistory: function (type) {
      var query = null;
      if (type) {
        query = "select * where state = '" + type + "'";
      }
      this.getCollection('notifications','notifications', 'created desc', query);
      var self = this;
      $rootScope.$on('notifications-received', function(event, notifications) {
        self.notificationCollection = notifications;
      });
    },
    getNotificationReceipts: function (uuid) {
      this.getCollection('receipts', 'notifications/'+uuid+'/receipts');
      var self = this;
      $rootScope.$on('receipts-received', function(event, receipts) {
        self.receiptsCollection = receipts;
      });
    },
    getIndexes: function (path) {
      var options = {
        method:'GET',
        endpoint: path.split('/').concat('indexes').filter(function(bit){return bit && bit.length}).join('/')
      }
      this.client().request(options, function (err, data) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'Problem getting indexes: ' + data.error);
        } else {
          $rootScope.$broadcast('indexes-received', data.data);
        }
      });
    },
    sendNotification: function(path, body) {
      var options = {
        method:'POST',
        endpoint: path,
        body:body
      }
      this.client().request(options, function (err, data) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'Problem creating notification: ' + data.error);
        } else {
          $rootScope.$broadcast('send-notification-complete');
        }
      });
    },
    getRolesUsers: function (username) {
      var self = this;
      var options = {
        type:'roles/users/'+username,
        qs:{ql:'order by username'}
      }
      this.client().createCollection(options, function (err, users) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error getting users');
        } else {
          $rootScope.$broadcast('users-received', users);

        }
      });
    },
    getTypeAheadData: function (type, searchString, searchBy, orderBy) {

      var self = this;
      var search = '';
      var qs = {limit: 100};
      if (searchString) {
        search = "select * where "+searchBy+" = '"+searchString+"'";
      }
      if (orderBy) {
        search = search + " order by "+orderBy;
      }
      if (search) {
        qs.ql = search;
      }
      var options = {
        method:'GET',
        endpoint: type,
        qs:qs
      }
      this.client().request(options, function (err, data) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error getting '+type);
        } else {
          var entities = data.entities;
          $rootScope.$broadcast(type +'-typeahead-received', entities);
        }
      });
    },
    getUsersTypeAhead: function (searchString) {
      this.getTypeAheadData('users', searchString, 'username', 'username');
    },
    getGroupsTypeAhead: function (searchString) {
      this.getTypeAheadData('groups', searchString, 'path', 'path');
    },
    getRolesTypeAhead: function (searchString) {
      this.getTypeAheadData('roles', searchString, 'name', 'name');
    },
    getGroupsForUser: function (user) {
      var self = this;
      var options = {
        type:'users/'+user+'/groups'
      }
      this.client().createCollection(options, function (err, groups) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error getting groups');
        } else {

          $rootScope.$broadcast('user-groups-received', groups);

        }
      });
    },
    addUserToGroup: function (user, group) {
      var self = this;
      var options = {
        type:'users/'+user+'/groups/'+group
      }
      this.client().createEntity(options, function (err, entity) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error adding user to group');
        } else {
          $rootScope.$broadcast('user-added-to-group-received');
        }
      });
    },
    addUserToRole: function (user, role) {
      var options = {
        method:'POST',
        endpoint:'roles/'+role+'/users/'+user
      };
      this.client().request(options, function (err, data) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error adding user to role');
        } else {
          $rootScope.$broadcast('role-update-received');
        }
      });
    },
    addGroupToRole: function (group, role) {
      var options = {
        method:'POST',
        endpoint:'roles/'+role+'/groups/'+group
      };
      this.client().request(options, function (err, data) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error adding group to role');
        } else {
          $rootScope.$broadcast('role-update-received');
        }
      });
    },
    followUser: function (user) {
      var self = this;
      var username =  $rootScope.selectedUser.get('uuid');
      var options = {
        method:'POST',
        endpoint:'users/'+username+'/following/users/'+user
      };
      this.client().request(options, function (err, data) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error following user');
        } else {
          $rootScope.$broadcast('follow-user-received');
        }
      });
    },
    newPermission: function (permission, type, entity) { //"get,post,put:/mypermission"
      var options = {
        method:'POST',
        endpoint:type+'/'+entity+'/permissions',
        body:{"permission":permission}
      };
      this.client().request(options, function (err, data) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error adding permission');
        } else {
          $rootScope.$broadcast('permission-update-received');
        }
      });
    },
    newUserPermission: function (permission, username) {
      this.newPermission(permission,'users',username)
    },
    newGroupPermission: function (permission, path) {
      this.newPermission(permission,'groups',path)
    },
    newRolePermission: function (permission, name) {
      this.newPermission(permission,'roles',name)
    },

    deletePermission: function (permission, type, entity) { //"get,post,put:/mypermission"
      var options = {
        method:'DELETE',
        endpoint:type+'/'+entity+'/permissions',
        qs:{permission:permission}
      };
      this.client().request(options, function (err, data) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error deleting permission');
        } else {
          $rootScope.$broadcast('permission-update-received');
        }
      });
    },
    deleteUserPermission: function (permission, user) {
      this.deletePermission(permission,'users',user);
    },
    deleteGroupPermission: function (permission, group) {
      this.deletePermission(permission,'groups',group);
    },
    deleteRolePermission: function (permission, rolename) {
      this.deletePermission(permission,'roles',rolename);
    },
    removeUserFromRole: function (user, role) { //"get,post,put:/mypermission"
      var options = {
        method:'DELETE',
        endpoint:'roles/'+role+'/users/'+user
      };
      this.client().request(options, function (err, data) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error removing user from role');
        } else {
          $rootScope.$broadcast('role-update-received');
        }
      });
    },
    removeUserFromGroup: function (group, role) { //"get,post,put:/mypermission"
      var options = {
        method:'DELETE',
        endpoint:'roles/'+role+'/groups/'+group
      };
      this.client().request(options, function (err, data) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error removing role from the group');
        } else {
          $rootScope.$broadcast('role-update-received');
        }
      });
    },
    createAndroidNotifier: function (name, APIkey) {
      var options = {
        method:'POST',
        endpoint:'notifiers',
        body:{"apiKey":APIkey,"name":name,"provider":"google"}
      };
      this.client().request(options, function (err, data) {
        if (err) {
          console.error(data);
          $rootScope.$broadcast('alert', 'error', 'error creating notifier ');
        } else {
          $rootScope.$broadcast('alert', 'success', 'New notifier created successfully.');
          $rootScope.$broadcast('notifier-update');
        }
      });

    },
    createAppleNotifier: function (file, name, environment, certificatePassword ) {

      var provider = 'apple';

      var formData = new FormData();
        formData.append("p12Certificate", file);

        formData.append('name', name);
        formData.append('provider', provider);
        formData.append('environment', environment);
        formData.append('certificatePassword', certificatePassword || "");
      //var body = {'p12Certificate':file, "name":name,'environment':environment,"provider":provider};
      //if(certificatePassword){
        //    body.certificatePassword = certificatePassword;
      //}
      var options = {
        method:'POST',
        endpoint:'notifiers',
        formData:formData
      };
      this.client().request(options, function (err, data) {
        if (err) {
          console.error(data);
          $rootScope.$broadcast('alert', 'error', data.error_description  || 'error creating notifier');
        } else {
          $rootScope.$broadcast('alert', 'success', 'New notifier created successfully.');
          $rootScope.$broadcast('notifier-update');
        }
      });

    },
    deleteNotifier: function (name) {
      var options = {
        method:'DELETE',
        endpoint: 'notifiers/'+name
      };
      this.client().request(options, function (err, data) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'error deleting notifier');
        } else {
          $rootScope.$broadcast('notifier-update');
        }
      });

    },
    initializeCurrentUser: function (callback) {
      callback = callback || function(){};
      if($rootScope.currentUser && !$rootScope.currentUser.reset){
        callback($rootScope.currentUser);
        return $rootScope.$broadcast('current-user-initialized', '');
      }
      var options = {
        method:'GET',
        endpoint:'management/users/'+ this.client().get('email'),
        mQuery:true
      };
      this.client().request(options, function (err, data) {
        if (err) {
          $rootScope.$broadcast('alert', 'error', 'Error getting user info');
        } else {
          $rootScope.currentUser = data.data;
          $rootScope.currentUser.profileImg = utility.get_gravatar($rootScope.currentUser.email);
          $rootScope.userEmail =$rootScope.currentUser.email;
          callback($rootScope.currentUser);
          $rootScope.$broadcast('current-user-initialized', $rootScope.currentUser);
        }
      });
    },

    updateUser: function (user) {
      var body = {};
      body.username = user.username;
      body.name = user.name;
      body.email = user.email;
      var options = {
        method:'PUT',
        endpoint:'management/users/' + user.uuid + '/',
        mQuery:true,
        body:body
      };
      var self = this;
      this.client().request(options, function (err, data) {
        self.client().set('email',user.email);
        self.client().set('username',user.username);
        if (err) {
          return $rootScope.$broadcast('user-update-error',data);
        }
        $rootScope.currentUser.reset = true;
        self.initializeCurrentUser(function(){
          $rootScope.$broadcast('user-update-success', $rootScope.currentUser);
        });
      });
    },

    resetUserPassword: function (user) {
      var body = {};
      body.oldpassword = user.oldPassword;
      body.newpassword = user.newPassword;
      body.username = user.username;
      var options = {
        method:'PUT',
        endpoint:'management/users/' + user.uuid + '/',
        body:body,
        mQuery:true
      }
      this.client().request(options, function (err, data) {
        if (err) {
         return  $rootScope.$broadcast('alert', 'error', 'Error resetting password');
        }
        //remove old and new password fields so they don't end up as part of the entity object
        $rootScope.currentUser.oldPassword = '';
        $rootScope.currentUser.newPassword = '';
        $rootScope.$broadcast('user-reset-password-success', $rootScope.currentUser);
      });

    },
    getOrgCredentials: function () {
      var options = {
        method:'GET',
        endpoint:'management/organizations/'+this.client().get('orgName')+'/credentials',
        mQuery:true
      };
      this.client().request(options, function (err, data) {
        if (err && data.credentials) {
          $rootScope.$broadcast('alert', 'error', 'Error getting credentials');
        } else {
          $rootScope.$broadcast('org-creds-updated', data.credentials);
        }
      });
    },
    regenerateOrgCredentials: function () {
      var self = this;
      var options = {
        method:'POST',
        endpoint:'management/organizations/'+ this.client().get('orgName') + '/credentials',
        mQuery:true
      };
      this.client().request(options, function(err, data) {
        if (err && data.credentials) {
          $rootScope.$broadcast('alert', 'error', 'Error regenerating credentials');
        } else {
          $rootScope.$broadcast('alert', 'success', 'Regeneration of credentials complete.');
          $rootScope.$broadcast('org-creds-updated', data.credentials);
        }
      });
    },
    getAppCredentials: function () {
      var options = {
        method:'GET',
        endpoint:'credentials'
      };
      this.client().request(options, function (err, data) {
        if (err && data.credentials) {
          $rootScope.$broadcast('alert', 'error', 'Error getting credentials');
        } else {
          $rootScope.$broadcast('app-creds-updated', data.credentials);
        }
      });
    },

    regenerateAppCredentials: function () {
      var self = this;
      var options = {
        method:'POST',
        endpoint:'credentials'
      };
      this.client().request(options, function(err, data) {
        if (err && data.credentials) {
          $rootScope.$broadcast('alert', 'error', 'Error regenerating credentials');
        } else {
          $rootScope.$broadcast('alert', 'success', 'Regeneration of credentials complete.');
          $rootScope.$broadcast('app-creds-updated', data.credentials);
        }
      });
    },

    signUpUser: function(orgName,userName,name,email,password){
      var formData = {
        "organization": orgName,
        "username": userName,
        "name": name,
        "email": email,
        "password": password
      };
      var options = {
        method:'POST',
        endpoint:'management/organizations',
        body:formData,
        mQuery:true
      };
      var client = this.client();
      client.request(options, function(err, data) {
        if (err) {
          $rootScope.$broadcast('register-error', data);
        } else {
          $rootScope.$broadcast('register-success',data);
        }
      });
    },
    resendActivationLink: function(id){
      var options = {
        method: 'GET',
        endpoint: 'management/users/'+id+'/reactivate',
        mQuery:true
      };
      this.client().request(options, function (err, data) {
        if (err) {
          $rootScope.$broadcast('resend-activate-error', data);
        } else {
          $rootScope.$broadcast('resend-activate-success',data);
        }
      });
    },
    getAppSettings: function(){
      $rootScope.$broadcast('app-settings-received',{});
    },
    getActivities: function(){
        this.client().request({method:'GET',endpoint:'activities', qs:{limit:200}},function(err,data){
          if(err) return $rootScope.$broadcast('app-activities-error',data);
          var entities = data.entities;
          //set picture if there is none and change gravatar to secure
          entities.forEach(function(entity) {
            if (!entity.actor.picture) {
              entity.actor.picture = window.location.protocol+ "//" + window.location.host + window.location.pathname + "img/user_profile.png"
            } else {
              entity.actor.picture = entity.actor.picture.replace(/^http:\/\/www.gravatar/i, 'https://secure.gravatar');
              //note: changing this to use the image on apigee.com - since the gravatar default won't work on any non-public domains such as localhost
              //this_data.picture = this_data.picture + encodeURI("?d="+window.location.protocol+"//" + window.location.host + window.location.pathname + "images/user_profile.png");
              if (~entity.actor.picture.indexOf('http')) {
                entity.actor.picture = entity.actor.picture;
              } else {
                entity.actor.picture = 'https://apigee.com/usergrid/img/user_profile.png';
              }
            }
        });
          $rootScope.$broadcast('app-activities-received',data.entities);
        });
    },
    getEntityActivities: function(entity, isFeed){
        var route = isFeed ? 'feed' : 'activities'
        var endpoint = entity.get('type') + '/' + entity.get('uuid') + '/'+route ;
        var options = {
          method:'GET',
          endpoint:endpoint,
          qs:{limit:200}
        };
        this.client().request(options, function (err, data) {
          if(err){
            $rootScope.$broadcast(entity.get('type')+'-'+route+'-error',data);
          }
          data.entities.forEach(function(entityInstance) {
            entityInstance.createdDate = (new Date( entityInstance.created)).toUTCString();
          });
          $rootScope.$broadcast(entity.get('type')+'-'+route+'-received',data.entities);
        });
    },
    addUserActivity:function(user,content){
      var options = {
        "actor": {
        "displayName": user.get('username'),
        "uuid": user.get('uuid'),
        "username":user.get('username')
          },
        "verb": "post",
        "content": content
      };
      this.client().createUserActivity(user.get('username'), options, function(err, activity) { //first argument can be 'me', a uuid, or a username
        if (err) {
          $rootScope.$broadcast('user-activity-add-error', err);
        } else {
          $rootScope.$broadcast('user-activity-add-success', activity);
        }
      });
    },
    runShellQuery:function(method,path,payload){
      var path = path.replace(/^\//, ''); //remove leading slash if it does
      var options = {
        "method": method,
        "endpoint":path
      };
      if(payload){
        options["body"]=payload;
      }
      this.client().request(options,function(err,data){
        if(err) {
          $rootScope.$broadcast('shell-error', data);
        }else{
          $rootScope.$broadcast('shell-success', data);
        }
      });
    },
    addOrganization:function(user,orgName){
      var options = {
        method: 'POST',
        endpoint: 'management/users/'+user.uuid+'/organizations',
        body:{organization:orgName},
        mQuery:true
          }, client = this.client(),self=this;
      client.request(options,function(err,data){
        if(err){
          $rootScope.$broadcast('user-add-org-error', data);
        }else{
          $rootScope.$broadcast('user-add-org-success', $rootScope.organizations);
        }
      });
    },
    leaveOrganization:function(user,org){
      var options = {
        method: 'DELETE',
        endpoint: 'management/users/'+user.uuid+'/organizations/'+org.uuid,
        mQuery:true
      }
      this.client().request(options,function(err,data){
        if(err){
          $rootScope.$broadcast('user-leave-org-error', data);
        }else{
          delete  $rootScope.organizations[org.name];
          $rootScope.$broadcast('user-leave-org-success', $rootScope.organizations);
        }
      });
    },
    /**
     * Retrieves page data
     * @param {string} id the name of the single page item to get (a key in the JSON) can be null.
     * @param {string} url location of the file/endpoint.
     * @return {Promise} Resolves to JSON.
     */
    httpGet: function (id, url) {
      var items, deferred;

      deferred = $q.defer();

      $http.get((url || configuration.ITEMS_URL)).
        success(function (data, status, headers, config) {
          var result;
          if (id) {
            angular.forEach(data, function (obj, index) {
              if (obj.id === id) {
                result = obj;
              }
            });
          } else {
            result = data;
          }
          deferred.resolve(result);
        }).
        error(function (data, status, headers, config) {
          $log.error(data, status, headers, config);
          reportError(data,config);
          deferred.reject(data);
        });

      return deferred.promise;
    },

    /**
     * Retrieves page data via jsonp
     * @param {string} url the location of the JSON/RESTful endpoint.
     * @param {string} successCallback function called on success.
     */

    jsonp: function (objectType,criteriaId,params,successCallback) {
      if(!params){
        params = {};
      }
      params.demoApp = $rootScope.demoData;
      params.access_token = getAccessToken();
      params.callback = 'JSON_CALLBACK';
      var uri = $rootScope.urls().DATA_URL  + '/' + $rootScope.currentOrg + '/' + $rootScope.currentApp + '/apm/' + objectType + '/' + criteriaId;
      return this.jsonpRaw(objectType,criteriaId,params,uri,successCallback);
    },

    jsonpSimple: function (objectType,appId,params) {
      var uri = $rootScope.urls().DATA_URL  + '/' + $rootScope.currentOrg + '/' + $rootScope.currentApp + '/apm/' + objectType + "/" + appId;
      return this.jsonpRaw(objectType,appId,params,uri);
    },
    calculateAverageRequestTimes: function(){
      if(!running){
        var self = this;
        running = true;
        setTimeout(function(){
          running=false;
          var length = requestTimes.length < 10 ? requestTimes.length  : 10;
          var sum = requestTimes.slice(0, length).reduce(function(a, b) { return a + b });
          var avg = sum / length;
          self.averageRequestTimes = avg/1000;
          if(self.averageRequestTimes > 5){
            $rootScope.$broadcast('request-times-slow',self.averageRequestTimes);
          }
        },3000);
      }
    },
    jsonpRaw: function (objectType,appId,params,uri,successCallback) {
      if(typeof successCallback !== 'function'){
        successCallback = null;
      }
      uri = uri || ($rootScope.urls().DATA_URL  + '/' + $rootScope.currentOrg + '/' + $rootScope.currentApp + '/' + objectType);

      if(!params){
        params = {};
      }

      var start = new Date().getTime(),
        self = this;

      params.access_token = getAccessToken();
      params.callback = 'JSON_CALLBACK';

      var deferred = $q.defer();

      var diff = function(){
        currentRequests[uri]--;
        requestTimes.splice(0,0 ,new Date().getTime() - start);
        self.calculateAverageRequestTimes();
      };

      successCallback && $rootScope.$broadcast("ajax_loading", objectType);
      var reqCount = currentRequests[uri] || 0;
      if(self.averageRequestTimes > 5 && reqCount>1){
        setTimeout(function(){
          deferred.reject(new Error('query in progress'));
        },50);
        return deferred;
      }
      currentRequests[uri] = (currentRequests[uri] || 0) + 1;

      $http.jsonp(uri,{params:params}).
        success(function(data, status, headers, config) {
          diff();
          if(successCallback){
            successCallback(data, status, headers, config);
            $rootScope.$broadcast("ajax_finished", objectType);
          }
          deferred.resolve(data);
        }).
        error(function(data, status, headers, config) {
          diff();
          $log.error("ERROR: Could not get jsonp data. " +uri);
          reportError(data,config);
          deferred.reject(data);
        });

      return deferred.promise;
    },

    resource: function(params,isArray) {
      //temporary url for REST endpoints

      return $resource($rootScope.urls().DATA_URL + '/:orgname/:appname/:username/:endpoint',
        {

        },
        {
          get: {
            method:'JSONP',
            isArray: isArray,
            params: params
          },
          login: {
            method:'GET',
            url: $rootScope.urls().DATA_URL + '/management/token',
            isArray: false,
            params: params
          },
          save: {
            url: $rootScope.urls().DATA_URL + '/' + params.orgname + '/' + params.appname,
            method:'PUT',
            isArray: false,
            params: params
          }
        });
    },

    httpPost: function(url,callback,payload,headers){

      var accessToken = getAccessToken();

      if(payload){
        payload.access_token = accessToken;
      }else{
        payload = {access_token:accessToken}
      }

      if(!headers){
        headers = {Bearer:accessToken};
      }

      $http({method: 'POST', url: url, data: payload, headers: headers}).
        success(function(data, status, headers, config) {
          callback(data)
        }).
        error(function(data, status, headers, config) {
          reportError(data,config);
          callback(data)
        });

    }
  }
});
