/*
*  This module is a collection of classes designed to make working with
*  the Appigee App Services API as easy as possible.
*  Learn more at http://apigee.com/docs/usergrid
*
*   Copyright 2012 Apigee Corporation
*
*  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.
*
*  @author rod simpson (rod@apigee.com)
*/
(function(window, localStorage){


//Hack around IE console.log
window.console = window.console || {};
window.console.log = window.console.log || function() {};

//Usergrid namespace encapsulates this SDK
window.Usergrid = window.Usergrid || {};
Usergrid = Usergrid || {};
Usergrid.SDK_VERSION = '0.10.07';
Usergrid.browser = Usergrid.browser || {};

Usergrid.Client = function(options,url) {
  //usergrid enpoint
  this.URI = url || 'https://api.usergrid.com';

  //Find your Orgname and Appname in the Admin portal (http://apigee.com/usergrid)
  if (options.orgName) {
    this.set('orgName', options.orgName);
  }
  if (options.appName) {
    this.set('appName', options.appName);
  }

  if(options.keys){
    this._keys = options.keys;
  }

  //other options
  this.buildCurl = options.buildCurl || false;
  this.logging = options.logging || false;

  //timeout and callbacks
  this._callTimeout =  options.callTimeout || 30000; //default to 30 seconds
  this._callTimeoutCallback =  options.callTimeoutCallback || null;
  this.logoutCallback =  options.logoutCallback || null;
};

/*
*  Main function for making requests to the API.  Can be called directly.
*
*  options object:
*  `method` - http method (GET, POST, PUT, or DELETE), defaults to GET
*  `qs` - object containing querystring values to be appended to the uri
*  `body` - object containing entity body for POST and PUT requests
*  `endpoint` - API endpoint, for example 'users/fred'
*  `mQuery` - boolean, set to true if running management query, defaults to false
*
*  @method request
*  @public
*  @params {object} options
*  @param {function} callback
*  @return {callback} callback(err, data)
*/
Usergrid.Client.prototype.request = function (options, callback) {
  callback = callback || function(){console.error('no callback handed to client.request().')};
  var self = this;
  var method = options.method || "GET";
  var endpoint = options.endpoint;
  var body = options.body || {};
  var qs = options.qs || {};
  var mQuery = options.mQuery || false;
  //is this a query to the management endpoint?
  var orgName = this.get("orgName");
  var appName = this.get("appName");
  if (!mQuery && !orgName && !appName) {
    if (typeof this.logoutCallback === "function") {
      return this.logoutCallback(true, "no_org_or_app_name_specified");
    }
  }
  var uri;
  if (mQuery) {
    uri = this.URI + "/" + endpoint;
  } else {
    uri = this.URI + "/" + orgName + "/" + appName + "/" + endpoint;
  }
  if (self.getToken()) {
    qs.access_token = self.getToken();
  }
  var developerkey=self.get("developerkey");
  if (developerkey) {
    qs.key = developerkey;  
  }

  var isIE9 = Usergrid.browser.isIE9 = $.browser.msie && $.browser.version <= 9;
  
  (isIE9) && (method === 'PUT' || method === 'DELETE') && (function(){ qs['method_override'] = method;})();
  
  //append params to the path
  var encoded_params = encodeParams(qs);
  if (encoded_params) {
    uri += "?" + encoded_params;
  }
  //stringify the body object
  body = options.formData ? null : JSON.stringify(body);
  //so far so good, so run the query
  //*** ie9 hack
  var xhr;
  //check to see if ie9 - if so, convert delete and put calls to a POST
  if (isIE9) { //XDomainRequest
    xhr = new XDomainRequest();
    (method === 'PUT' || method === 'DELETE') && (function() { method = 'POST';})();
    xhr.open(method, uri);
  }else{
    xhr = new XMLHttpRequest();
    xhr.open(method, uri, true);
    //add content type = json if there is a json payload
    if (!options.formData) {
      xhr.setRequestHeader("Content-Type", "application/json");
      xhr.setRequestHeader("Accept", "application/json");
    }
  }
  xhr.isIE9 = isIE9;
  // Handle response.
  xhr.onerror = function(response) {
    self._end = new Date().getTime();
    if (self.logging) {
      console.log("success (time: " + self.calcTimeDiff() + "): " + method + " " + uri);
    }
    if (self.logging) {
      console.log("Error: API call failed at the network level.");
    }
    //network error
    clearTimeout(timeout);
    var err = true;
    if (typeof callback === "function") {
      callback(err, response);
    }
  };
  xhr.onload = function(response) {
    //call timing, get time, then log the call
    self._end = new Date().getTime();
    if (self.logging) {
      console.log("success (time: " + self.calcTimeDiff() + "): " + method + " " + uri);
    }
    //call completed
    clearTimeout(timeout);
    //decode the response
    try {
      response = JSON.parse(xhr.responseText);
    } catch (e) {
      response = {
        error: "unhandled_error",
        error_description: xhr.responseText
      };
      xhr.status = xhr.status === 200 ? 400 : xhr.status;
      console.error(e);
    }
    if (!xhr.isIE9 && xhr.status != 200) {
      //there was an api error
      var error = response.error;
      var error_description = response.error_description;
      if (self.logging) {
        console.log("Error (" + xhr.status + ")(" + error + "): " + error_description);
      }
      if (error == "auth_expired_session_token" || error == "auth_missing_credentials" || error == "auth_unverified_oath" || error == "expired_token" || error == "unauthorized" || error == "auth_invalid") {
        //these errors mean the user is not authorized for whatever reason. If a logout function is defined, call it
        //if the user has specified a logout callback:
        if (typeof self.logoutCallback === "function") {
          return self.logoutCallback(true, response);
        }
      }
      if (typeof callback === "function") {
        callback(true, response);
      }
    } else {
      if (typeof callback === "function") {
        callback(false, response);
      }
    }
  };
  var timeout = setTimeout(function() {
    xhr.abort();
    if (self._callTimeoutCallback === "function") {
      self._callTimeoutCallback("API CALL TIMEOUT");
    } else {
      callback("API CALL TIMEOUT");
    }
  }, self._callTimeout);
  //set for 30 seconds
  if (this.logging) {
    console.log("calling: " + method + " " + uri);
  }
  if (this.buildCurl) {
    var curlOptions = {
      uri: uri,
      body: body,
      method: method
    };
    this.buildCurlCall(curlOptions);
  }
  this._start = new Date().getTime();
  xhr.send(options.formData || body);
};

Usergrid.Client.prototype.keys = function(o) {
  var a = [];
  for (var propertyName in o) {
    a.push(propertyName);
  }
  return a;
}

/*
 *  Main function for creating new groups. Call this directly.
 *
 *  @method createGroup
 *  @public
 *  @params {string} path
 *  @param {function} callback
 *  @return {callback} callback(err, data)
 */
Usergrid.Client.prototype.createGroup = function(options, callback) {
  var getOnExist = options.getOnExist || false;

  var options = {
    path: options.path,
    client: this,
    data:options 
  }

  var group = new Usergrid.Group(options);
  group.fetch(function(err, data){
    var okToSave = (err && ('service_resource_not_found' === data.error || 'no_name_specified' === data.error || 'null_pointer' === data.error || Usergrid.browser.isIE9)) || (!err && getOnExist);
    if (okToSave) {
      group.save(function(err, data){
        if (typeof(callback) === 'function') {
          callback(err, group);
        }
      });
    } else {
      if(typeof(callback) === 'function') {
        callback(err, group);
      }
    }
  });
}

/*
*  Main function for creating new entities - should be called directly.
*
*  options object: options {data:{'type':'collection_type', 'key':'value'}, uuid:uuid}}
*
*  @method createEntity
*  @public
*  @params {object} options
*  @param {function} callback
*  @return {callback} callback(err, data)
*/
Usergrid.Client.prototype.createEntity = function (options, callback) {
  // todo: replace the check for new / save on not found code with simple save
  // when users PUT on no user fix is in place.
  /*
  var options = {
    client:this,
    data:options
  }
  var entity = new Usergrid.Entity(options);
  entity.save(function(err, data) {
    if (typeof(callback) === 'function') {
      callback(err, entity);
    }
  });
  */
  var getOnExist = options.getOnExist || false; //if true, will return entity if one already exists
  var options = {
    client:this,
    data:options
  }
  var entity = new Usergrid.Entity(options);
  entity.fetch(function(err, data) {
    //if the fetch doesn't find what we are looking for, or there is no error, do a save
    if (Usergrid.browser.isIE9 || 'service_resource_not_found' === data.error || 'no_name_specified' === data.error || 'null_pointer' === data.error) {

      entity.set(options.data); //add the data again just in case
      entity.save(function(err, data) {
        if (typeof(callback) === 'function') {
          callback(err, entity, data);
        }
      });

    } else {
      if (getOnExist) {
        // entity exists and they want it returned
        if (typeof(callback) === 'function') {
          callback(err, entity, data);
        }
      } else {
        //entity exists but they want an error to that effect
        err = true;
        callback(err, 'duplicate entity already exists');
      }
    }

  });

}

/*
 *  Main function for getting existing entities - should be called directly.
 *
 *  You must supply a uuid or (username or name). Username only applies to users.
 *  Name applies to all custom entities
 *
 *  options object: options {data:{'type':'collection_type', 'name':'value', 'username':'value'}, uuid:uuid}}
 *
 *  @method createEntity
 *  @public
 *  @params {object} options
 *  @param {function} callback
 *  @return {callback} callback(err, data)
 */
Usergrid.Client.prototype.getEntity = function (options, callback) {
  var options = {
    client:this,
    data:options
  }
  var entity = new Usergrid.Entity(options);
  entity.fetch(function(err, data) {
    if (typeof(callback) === 'function') {
      callback(err, entity, data);
    }
  });
}
/*
 *  Main function for restoring an entity from serialized data.
 *
 *  serializedObject should have come from entityObject.serialize();
 *
 *  @method restoreEntity
 *  @public
 *  @param {string} serializedObject
 *  @return {object} Entity Object
 */
Usergrid.Client.prototype.restoreEntity = function (serializedObject) {
  var data = JSON.parse(serializedObject);
  var options = {
    client:this,
    data:data
  }
  var entity = new Usergrid.Entity(options);
  return entity;
}

/*
*  Main function for creating new collections - should be called directly.
*
*  options object: options {client:client, type: type, qs:qs}
*
*  @method createCollection
*  @public
*  @params {object} options
*  @param {function} callback
*  @return {callback} callback(err, data)
*/
Usergrid.Client.prototype.createCollection = function (options, callback) {
  options.client = this;
  var collection = new Usergrid.Collection(options, function(err, data) {
    if (typeof(callback) === 'function') {
      callback(err, collection, data);
    }
  });
}

/*
 *  Main function for restoring a collection from serialized data.
 *
 *  serializedObject should have come from collectionObject.serialize();
 *
 *  @method restoreCollection
 *  @public
 *  @param {string} serializedObject
 *  @return {object} Collection Object
 */
Usergrid.Client.prototype.restoreCollection = function (serializedObject) {
  var data = JSON.parse(serializedObject);
  data.client = this;
  var collection = new Usergrid.Collection(data);
  return collection;
}

/*
 *  Main function for retrieving a user's activity feed.
 *
 *  @method getFeedForUser
 *  @public
 *  @params {string} username
 *  @param {function} callback
 *  @return {callback} callback(err, data, activities)
 */
Usergrid.Client.prototype.getFeedForUser = function(username, callback) {
  var options = {
    method: "GET",
    endpoint: "users/"+username+"/feed"
  }

  this.request(options, function(err, data){
    if(typeof(callback) === "function") {
      if(err) {
        callback(err);
      } else {
        callback(err, data, data.entities);
      }
    }
  });
}

/*
*  Function for creating new activities for the current user - should be called directly.
*
*  //user can be any of the following: "me", a uuid, a username
*  Note: the "me" alias will reference the currently logged in user (e.g. 'users/me/activties')
*
*  //build a json object that looks like this:
*  var options =
*  {
*    "actor" : {
*      "displayName" :"myusername",
*      "uuid" : "myuserid",
*      "username" : "myusername",
*      "email" : "myemail",
*      "picture": "http://path/to/picture",
*      "image" : {
*          "duration" : 0,
*          "height" : 80,
*          "url" : "http://www.gravatar.com/avatar/",
*          "width" : 80
*      },
*    },
*    "verb" : "post",
*    "content" : "My cool message",
*    "lat" : 48.856614,
*    "lon" : 2.352222
*  }

*
*  @method createEntity
*  @public
*  @params {string} user // "me", a uuid, or a username
*  @params {object} options
*  @param {function} callback
*  @return {callback} callback(err, data)
*/
Usergrid.Client.prototype.createUserActivity = function (user, options, callback) {
  options.type = 'users/'+user+'/activities';
  var options = {
    client:this,
    data:options
  }
  var entity = new Usergrid.Entity(options);
  entity.save(function(err, data) {
    if (typeof(callback) === 'function') {
      callback(err, entity);
    }
  });
}

/*
 *  Function for creating user activities with an associated user entity.
 *
 *  user object:
 *  The user object passed into this function is an instance of Usergrid.Entity.
 *
 *  @method createUserActivityWithEntity
 *  @public
 *  @params {object} user
 *  @params {string} content
 *  @param {function} callback
 *  @return {callback} callback(err, data)
 */
Usergrid.Client.prototype.createUserActivityWithEntity = function(user, content, callback) {
  var username = user.get("username");
  var options = {
    actor: {
      "displayName":username,
      "uuid":user.get("uuid"),
      "username":username,
      "email":user.get("email"),
      "picture":user.get("picture"),
      "image": {
        "duration":0,
        "height":80,
        "url":user.get("picture"),
        "width":80
       },
    },
    "verb":"post",
    "content":content };

    this.createUserActivity(username, options, callback);

}

/*
*  A private method to get call timing of last call
*/
Usergrid.Client.prototype.calcTimeDiff = function () {
 var seconds = 0;
 var time = this._end - this._start;
 try {
    seconds = ((time/10) / 60).toFixed(2);
 } catch(e) { return 0; }
 return seconds;
}

/*
 *  A public method to store the OAuth token for later use - uses localstorage if available
 *
 *  @method setToken
 *  @public
 *  @params {string} token
 *  @return none
 */
Usergrid.Client.prototype.setToken = function (token) {
  this.set('token', token);
}

/*
 *  A public method to get the OAuth token
 *
 *  @method getToken
 *  @public
 *  @return {string} token
 */
Usergrid.Client.prototype.getToken = function () {
  return this.get('token');
}

Usergrid.Client.prototype.setObject = function(key, value) {
  if (value) {
    value = JSON.stringify(value);
  }
  this.set(key, value);
}

Usergrid.Client.prototype.set = function (key, value) {
  var keyStore =  'apigee_' + key;
  this[key] = value;
  if(typeof(Storage)!=="undefined"){
    if (value) {
      localStorage.setItem(keyStore, value);
    } else {
      localStorage.removeItem(keyStore);
    }
  }
}

Usergrid.Client.prototype.getObject = function(key) {
  return JSON.parse(this.get(key));
}

Usergrid.Client.prototype.get = function (key) {
  var keyStore = 'apigee_' + key;
  if (this[key]) {
    return this[key];
  } else if(typeof(Storage)!=="undefined") {
    return localStorage.getItem(keyStore);
  }
  return null;
}

/*
 * A public facing helper method for signing up users
 *
 * @method signup
 * @public
 * @params {string} username
 * @params {string} password
 * @params {string} email
 * @params {string} name
 * @param {function} callback
 * @return {callback} callback(err, data)
 */
Usergrid.Client.prototype.signup = function(username, password, email, name, callback) {
  var self = this;
  var options = {
    type:"users",
    username:username,
    password:password,
    email:email,
    name:name
  };

  this.createEntity(options, callback);
}

/*
*
*  A public method to log in an app user - stores the token for later use
*
*  @method login
*  @public
*  @params {string} username
*  @params {string} password
*  @param {function} callback
*  @return {callback} callback(err, data)
*/
Usergrid.Client.prototype.login = function (username, password, callback) {
  var self = this;
  var options = {
    method:'POST',
    endpoint:'token',
    body:{
      username: username,
      password: password,
      grant_type: 'password'
    }
  };
  this.request(options, function(err, data) {
    var user = {};
    if (err && self.logging) {
      console.log('error trying to log user in');
    } else {
      var options = {
        client:self,
        data:data.user
      }
      user = new Usergrid.Entity(options);
      self.setToken(data.access_token);
    }
    if (typeof(callback) === 'function') {
      callback(err, data, user);
    }
  });
}


Usergrid.Client.prototype.reAuthenticateLite = function (callback) {
  var self = this;
  var options = {
    method:'GET',
    endpoint:'management/me',
    mQuery:true
  };
  this.request(options, function(err, response) {
    if (err && self.logging) {
      console.log('error trying to re-authenticate user');
    } else {

      //save the re-authed token and current email/username
      self.setToken(response.access_token);

    }
    if (typeof(callback) === 'function') {
      callback(err);
    }
  });
}


Usergrid.Client.prototype.reAuthenticate = function (email, callback) {
  var self = this;
  var options = {
    method:'GET',
    endpoint:'management/users/'+email,
    mQuery:true
  };
  this.request(options, function(err, response) {
    var organizations = {};
    var applications = {};
    var user = {};
    if (err && self.logging) {
      console.log('error trying to full authenticate user');
    } else {
      var data = response.data;
      self.setToken(data.token);
      self.set('email', data.email);

      //delete next block and corresponding function when iframes are refactored
      localStorage.setItem('accessToken', data.token);
      localStorage.setItem('userUUID', data.uuid);
      localStorage.setItem('userEmail', data.email);
      //end delete block


      var userData = {
        "username" : data.username,
        "email" : data.email,
        "name" : data.name,
        "uuid" : data.uuid
      }
      var options = {
        client:self,
        data:userData
      }
      user = new Usergrid.Entity(options);

      organizations = data.organizations;
      var org = '';
      try {
        //if we have an org stored, then use that one. Otherwise, use the first one.
        var existingOrg = self.get('orgName');
        org = (organizations[existingOrg])?organizations[existingOrg]:organizations[Object.keys(organizations)[0]];
        self.set('orgName', org.name);
      } catch(e) {
        err = true;
        if (self.logging) { console.log('error selecting org'); }
      } //should always be an org

      applications = self.parseApplicationsArray(org);
      self.selectFirstApp(applications);

      self.setObject('organizations', organizations);
      self.setObject('applications', applications);

    }
    if (typeof(callback) === 'function') {
      callback(err, data, user, organizations, applications);
    }
  });
}

Usergrid.Client.prototype.orgLogin = function (username, password, callback) {
  var self = this;
  var options = {
    method:'POST',
    endpoint:'management/token',
    mQuery:true,
    body:{
      username: username,
      password: password,
      grant_type: 'password'
    }
  };
  this.request(options, function(err, data) {
    var user = {};
    var organizations = {};
    var applications = {};
    if (err && self.logging) {
      console.log('error trying to log user in');
    } else {
      var options = {
        client:self,
        data:data.user
      }
      user = new Usergrid.Entity(options);
      self.setToken(data.access_token);
      self.set('email', data.user.email);


      //delete next block and corresponding function when iframes are refactored
      localStorage.setItem('accessToken', data.access_token);
      localStorage.setItem('userUUID', data.user.uuid);
      localStorage.setItem('userEmail', data.user.email);
      //end delete block


      organizations = data.user.organizations;
      var org = '';
      try {
        //if we have an org stored, then use that one. Otherwise, use the first one.
        var existingOrg = self.get('orgName');
        org = (organizations[existingOrg])?organizations[existingOrg]:organizations[Object.keys(organizations)[0]];
        self.set('orgName', org.name);
      } catch(e) {
        err = true;
        if (self.logging) { console.log('error selecting org'); }
      } //should always be an org

      applications = self.parseApplicationsArray(org);
      self.selectFirstApp(applications);

      self.setObject('organizations', organizations);
      self.setObject('applications', applications);

    }
    if (typeof(callback) === 'function') {
      callback(err, data, user, organizations, applications);
    }
  });
}

Usergrid.Client.prototype.parseApplicationsArray = function (org) {
  var applications = {};

  for (var key in org.applications) {
    var uuid = org.applications[key];
    var name = key.split("/")[1];
    applications[name] = ({uuid:uuid, name:name});
  }

  return applications;
}

Usergrid.Client.prototype.selectFirstApp = function (applications) {
  try {
    //try to select an app if one exists (will use existing if possible)
    var existingApp = this.get('appName');
    var firstApp = Object.keys(applications)[0];
    var appName = (applications[existingApp])?existingApp:Object.keys(applications)[0];
    this.set('appName', appName);
  } catch(e){}//may or may not be an application, if no, just fall through
  return appName;
}

Usergrid.Client.prototype.createApplication = function (name, callback) {
  var self = this;
  var options = {
    method:'POST',
    endpoint:'management/organizations/'+ this.get('orgName') + '/applications',
    mQuery:true,
    body:{name:name}
  };
  this.request(options, function(err, response) {
    var applications = {};
    if (err && self.logging) {
      console.log('error trying to create new application');
      if (typeof(callback) === 'function') {
        callback(err, applications);
      }
    } else {
      self.getApplications(callback);
    }
  });
}

Usergrid.Client.prototype.getApplications = function(callback) {
  var self = this;
  var options = {
    method:'GET',
    endpoint:'management/organizations/'+this.get('orgName')+'/applications',
    mQuery:true
  };
  this.request(options, function(err, data) {
/*
    //grab the applications
    var applicationsData = data.data;
    var applicationNames = self.keys(applicationsData).sort();
    var firstApp = '';
    var applications = [];
    var count = 0;
    for (var i in applicationNames) {
      var name = applicationNames[i];
      var uuid = applicationsData[name];
      name = name.split("/")[1];
      applications.push({uuid:uuid, name:name});
      if (count===0) {
        firstApp = name;
      }
      count++;
    } */

    applications = self.parseApplicationsArray({applications:data.data});
    self.selectFirstApp(applications);
    self.setObject('applications',applications);

    if(typeof(callback) === 'function') {
      callback(err, applications);
    }
  });
}

Usergrid.Client.prototype.getAdministrators = function (callback) {
  var self = this;
  var options = {
    method:'GET',
    endpoint:'management/organizations/'+this.get('orgName')+'/users',
    mQuery:true
  };
  this.request(options, function (err, data) {
    var administrators = [];
    if (err) {

    } else {
      var administrators = [];
      for(var i in data.data) {
        var admin = data.data[i];
        admin.image = self.getDisplayImage(admin.email, admin.picture);
        administrators.push(admin);
      }
    }

    if (typeof(callback) === 'function') {
      callback(err, administrators);
    }
  });
}


Usergrid.Client.prototype.createAdministrator = function (email, callback) {
  var self = this;
  var options = {
    method:'POST',
    endpoint:'management/organizations/'+ this.get('orgName') + '/users',
    mQuery:true,
    body:{email:email, password:''}
  };
  this.request(options, function(err, response) {
    var admins = {};
    if (err && self.logging) {
      console.log('error trying to create new administrator');
      if (typeof(callback) === 'function') {
        callback(err, admins);
      }
    } else {
      self.getAdministrators(callback);
    }
  });
}






/*
*  A public method to log in an app user with facebook - stores the token for later use
*
*  @method loginFacebook
*  @public
*  @params {string} username
*  @params {string} password
*  @param {function} callback
*  @return {callback} callback(err, data)
*/
Usergrid.Client.prototype.loginFacebook = function (facebookToken, callback) {
  var self = this;
  var options = {
    method:'GET',
    endpoint:'auth/facebook',
    qs:{
      fb_access_token: facebookToken
    }
  };
  this.request(options, function(err, data) {
    var user = {};
    if (err && self.logging) {
      console.log('error trying to log user in');
    } else {
      var options = {
        client: self,
        data: data.user
      }
      user = new Usergrid.Entity(options);
      self.setToken(data.access_token);
    }
    if (typeof(callback) === 'function') {
      callback(err, data, user);
    }
  });
}

/*
*  A public method to get the currently logged in user entity
*
*  @method getLoggedInUser
*  @public
*  @param {function} callback
*  @return {callback} callback(err, data)
*/
Usergrid.Client.prototype.getLoggedInUser = function (callback) {
  if (!this.getToken()) {
    callback(true, null, null);
  } else {
    var self = this;
    var options = {
      method:'GET',
      endpoint:'users/me'
    };
    this.request(options, function(err, data) {
      if (err) {
        if (self.logging) {
          console.log('error trying to log user in');
        }
        if (typeof(callback) === 'function') {
          callback(err, data, null);
        }
      } else {
        var options = {
          client:self,
          data:data.entities[0]
        }
        var user = new Usergrid.Entity(options);
        if (typeof(callback) === 'function') {
          callback(err, data, user);
        }
      }
    });
  }
}

/*
*  A public method to test if a user is logged in - does not guarantee that the token is still valid,
*  but rather that one exists
*
*  @method isLoggedIn
*  @public
*  @return {boolean} Returns true the user is logged in (has token and uuid), false if not
*/
Usergrid.Client.prototype.isLoggedIn = function () {
  if (this.getToken()) {
    return true;
  }
  return false;
}

/*
*  A public method to log out an app user - clears all user fields from client
*
*  @method logout
*  @public
*  @return none
*/
Usergrid.Client.prototype.logout = function () {
  this.setToken(null);
  this.setObject('organizations', null);
  this.setObject('applications', null);
  this.set('orgName', null);
  this.set('appName', null);
  this.set('email', null);
  this.set("developerkey", null);
}

/*
*  A private method to build the curl call to display on the command line
*
*  @method buildCurlCall
*  @private
*  @param {object} options
*  @return {string} curl
*/
Usergrid.Client.prototype.buildCurlCall = function (options) {
  var curl = 'curl';
  var method = (options.method || 'GET').toUpperCase();
  var body = options.body || {};
  var uri = options.uri;

  //curl - add the method to the command (no need to add anything for GET)
  if (method === 'POST') {curl += ' -X POST'; }
  else if (method === 'PUT') { curl += ' -X PUT'; }
  else if (method === 'DELETE') { curl += ' -X DELETE'; }
  else { curl += ' -X GET'; }

  //curl - append the path
  curl += ' ' + uri;

  //curl - add the body
  if (body !== '"{}"' && method !== 'GET' && method !== 'DELETE') {
    //curl - add in the json obj
    curl += " -d '" + body + "'";
  }

  //log the curl command to the console
  console.log(curl);

  return curl;
}
Usergrid.Client.prototype.getDisplayImage = function (email, picture, size) {
  try {
    if (picture) {
      return picture;
    }
    var size = size || 50;
    if (email.length) {
      return 'https://secure.gravatar.com/avatar/' + MD5(email) + '?s=' + size;
    } else {
      return 'https://apigee.com/usergrid/img/user_profile.png';
    }
  } catch(e) {
    return 'https://apigee.com/usergrid/img/user_profile.png';
  }
}

/*
*  A class to Model a Usergrid Entity.
*  Set the type of entity in the 'data' json object
*
*  @constructor
*  @param {object} options {client:client, data:{'type':'collection_type', 'key':'value'}, uuid:uuid}}
*/
Usergrid.Entity = function(options) {
  if (options) {
    this._data = options.data || {};
    this._client = options.client || {};
  }
};

/*
 *  returns a serialized version of the entity object
 *
 *  Note: use the client.restoreEntity() function to restore
 *
 *  @method serialize
 *  @return {string} data
 */
Usergrid.Entity.prototype.serialize = function () {
  return JSON.stringify(this._data);
}

/*
*  gets a specific field or the entire data object. If null or no argument
*  passed, will return all data, else, will return a specific field
*
*  @method get
*  @param {string} field
*  @return {string} || {object} data
*/
Usergrid.Entity.prototype.get = function (field) {
  if (field) {
    return this._data[field];
  } else {
    return this._data;
  }
}

/*
*  adds a specific key value pair or object to the Entity's data
*  is additive - will not overwrite existing values unless they
*  are explicitly specified
*
*  @method set
*  @param {string} key || {object}
*  @param {string} value
*  @return none
*/
Usergrid.Entity.prototype.set = function (key, value) {
  if (typeof key === 'object') {
    for(var field in key) {
      this._data[field] = key[field];
    }
  } else if (typeof key === 'string') {
    if (value === null) {
      delete this._data[key];
    } else {
      this._data[key] = value;
    }
  } else {
    this._data = {};
  }
}

/*
*  Saves the entity back to the database
*
*  @method save
*  @public
*  @param {function} callback
*  @return {callback} callback(err, data)
*/
Usergrid.Entity.prototype.save = function (callback) {
  var type = this.get('type');
  var method = 'POST';
  if (isUUID(this.get('uuid'))) {
    method = 'PUT';
    type += '/' + this.get('uuid');
  }

  //update the entity
  var self = this;
  var data = {};
  var entityData = this.get();
  //remove system specific properties
  for (var item in entityData) {
    if (item === 'metadata' || item === 'created' || item === 'modified' ||
        item === 'type' || item === 'activated' || item ==='uuid') { continue; }
    data[item] = entityData[item];
  }
  var options =  {
    method:method,
    endpoint:type,
    body:data
  };
  //save the entity first
  this._client.request(options, function (err, retdata) {
    if (err && self._client.logging) {
      console.log('could not save entity');
      if (typeof(callback) === 'function') {
        return callback(err, retdata, self);
      }
    } else {
      if (retdata.entities) {
        if (retdata.entities.length) {
          var entity = retdata.entities[0];
          self.set(entity);
          //for connections, API returns type
          self.set('type', retdata.path);
        }
      }
      //if this is a user, update the password if it has been specified;
      var needPasswordChange = (self.get('type') === 'user' && entityData.oldpassword && entityData.newpassword);
      if (needPasswordChange) {
        //Note: we have a ticket in to change PUT calls to /users to accept the password change
        //      once that is done, we will remove this call and merge it all into one
        var pwdata = {};
        pwdata.oldpassword = entityData.oldpassword;
        pwdata.newpassword = entityData.newpassword;
        var options = {
          method:'PUT',
          endpoint:type+'/password',
          body:pwdata
        }
        self._client.request(options, function (err, data) {
          if (err && self._client.logging) {
            console.log('could not update user');
          }
          //remove old and new password fields so they don't end up as part of the entity object
          self.set('oldpassword', null);
          self.set('newpassword', null);
          if (typeof(callback) === 'function') {
            callback(err, data, self);
          }
        });
      } else if (typeof(callback) === 'function') {
        callback(err, retdata, self);
      }
    }
  });
}

/*
*  refreshes the entity by making a GET call back to the database
*
*  @method fetch
*  @public
*  @param {function} callback
*  @return {callback} callback(err, data)
*/
Usergrid.Entity.prototype.fetch = function (callback) {
  var type = this.get('type');
  var self = this;

  //if a uuid is available, use that, otherwise, use the name
  if (this.get('uuid')) {
    type += '/' + this.get('uuid');
  } else {
    if (type === 'users') {
      if (this.get('username')) {
        type += '/' + this.get('username');
      } else {
        if (typeof(callback) === 'function') {
          var error = 'no_name_specified';
          if (self._client.logging) {
            console.log(error);
          }
          return callback(true, {error:error}, self)
        }
      }
    } else if (type === 'a path') {

      ///TODO add code to deal with the type as a path

      if (this.get('path')) {
        type += '/' + encodeURIComponent(this.get('name'));
      } else {
        if (typeof(callback) === 'function') {
          var error = 'no_name_specified';
          if (self._client.logging) {
            console.log(error);
          }
          return callback(true, {error:error}, self)
        }
      }

    } else {
      if (this.get('name')) {
        type += '/' + encodeURIComponent(this.get('name'));
      } else {
        if (typeof(callback) === 'function') {
          var error = 'no_name_specified';
          if (self._client.logging) {
            console.log(error);
          }
          return callback(true, {error:error}, self)
        }
      }
    }
  }
  var options = {
    method:'GET',
    endpoint:type
  };
  this._client.request(options, function (err, data) {
    if (err && self._client.logging) {
      console.log('could not get entity');
    } else {
      if (data.user) {
        self.set(data.user);
        self._json = JSON.stringify(data.user, null, 2);
      } else if (data.entities) {
        if (data.entities.length) {
          var entity = data.entities[0];
          self.set(entity);
        }
      }
    }
    if (typeof(callback) === 'function') {
      callback(err, data, self);
    }
  });
}

/*
*  deletes the entity from the database - will only delete
*  if the object has a valid uuid
*
*  @method destroy
*  @public
*  @param {function} callback
*  @return {callback} callback(err, data)
*
*/
Usergrid.Entity.prototype.destroy = function (callback) {
  var type = this.get('type');
  if (isUUID(this.get('uuid'))) {
    type += '/' + this.get('uuid');
  } else {
    if (typeof(callback) === 'function') {
      var error = 'Error trying to delete object - no uuid specified.';
      if (self._client.logging) {
        console.log(error);
      }
      callback(true, error);
    }
  }
  var self = this;
  var options = {
    method:'DELETE',
    endpoint:type
  };
  this._client.request(options, function (err, data) {
    if (err && self._client.logging) {
      console.log('entity could not be deleted');
    } else {
      self.set(null);
    }
    if (typeof(callback) === 'function') {
      callback(err, data);
    }
  });
}

/*
*  connects one entity to another
*
*  @method connect
*  @public
*  @param {string} connection
*  @param {object} entity
*  @param {function} callback
*  @return {callback} callback(err, data)
*
*/
Usergrid.Entity.prototype.connect = function (connection, entity, callback) {

  var self = this;

  //connectee info
  var connecteeType = entity.get('type');
  var connectee = this.getEntityId(entity);
  if (!connectee) {
    if (typeof(callback) === 'function') {
      var error = 'Error trying to delete object - no uuid specified.';
      if (self._client.logging) {
        console.log(error);
      }
      callback(true, error);
    }
    return;
  }

  //connector info
  var connectorType = this.get('type');
  var connector = this.getEntityId(this);
  if (!connector) {
    if (typeof(callback) === 'function') {
      var error = 'Error in connect - no uuid specified.';
      if (self._client.logging) {
        console.log(error);
      }
      callback(true, error);
    }
    return;
  }

  var endpoint = connectorType + '/' + connector + '/' + connection + '/' + connecteeType + '/' + connectee;
  var options = {
    method:'POST',
    endpoint:endpoint
  };
  this._client.request(options, function (err, data) {
    if (err && self._client.logging) {
      console.log('entity could not be connected');
    }
    if (typeof(callback) === 'function') {
      callback(err, data);
    }
  });
}

/*
*  returns a unique identifier for an entity
*
*  @method connect
*  @public
*  @param {object} entity
*  @param {function} callback
*  @return {callback} callback(err, data)
*
*/
Usergrid.Entity.prototype.getEntityId = function (entity) {
  var id = false;
  if (isUUID(entity.get('uuid'))) {
    id = entity.get('uuid');
  } else {
    if (type === 'users') {
      id = entity.get('username');
    } else if (entity.get('name')) {
      id = entity.get('name');
    }
  }
  return id;
}

/*
*  gets an entities connections
*
*  @method getConnections
*  @public
*  @param {string} connection
*  @param {object} entity
*  @param {function} callback
*  @return {callback} callback(err, data, connections)
*
*/
Usergrid.Entity.prototype.getConnections = function (connection, callback) {

  var self = this;

  //connector info
  var connectorType = this.get('type');
  var connector = this.getEntityId(this);
  if (!connector) {
    if (typeof(callback) === 'function') {
      var error = 'Error in getConnections - no uuid specified.';
      if (self._client.logging) {
        console.log(error);
      }
      callback(true, error);
    }
    return;
  }

  var endpoint = connectorType + '/' + connector + '/' + connection + '/';
  var options = {
    method:'GET',
    endpoint:endpoint
  };
  this._client.request(options, function (err, data) {
    if (err && self._client.logging) {
      console.log('entity could not be connected');
    }

    self[connection] = {};

    var length = data.entities.length;
    for (var i=0;i<length;i++)
    {
      if (data.entities[i].type === 'user'){
        self[connection][data.entities[i].username] = data.entities[i];
      } else {
        self[connection][data.entities[i].name] = data.entities[i]
      }
    }

    if (typeof(callback) === 'function') {
      callback(err, data, data.entities);
    }
  });

}

Usergrid.Entity.prototype.getGroups = function (callback) {

  var self = this;

  var endpoint = 'users' + '/' + this.get('uuid') + '/groups' ;
  var options = {
    method:'GET',
    endpoint:endpoint
  };
  this._client.request(options, function (err, data) {
    if (err && self._client.logging) {
      console.log('entity could not be connected');
    }

    self['groups'] = data.entities;

    if (typeof(callback) === 'function') {
      callback(err, data, data.entities);
    }
  });

}

Usergrid.Entity.prototype.getActivities = function (callback) {

  var self = this;

  var endpoint = this.get('type') + '/' + this.get('uuid') + '/activities' ;
  var options = {
    method:'GET',
    endpoint:endpoint
  };
  this._client.request(options, function (err, data) {
    if (err && self._client.logging) {
      console.log('entity could not be connected');
    }

    for(entity in data.entities) {
      data.entities[entity].createdDate = (new Date(data.entities[entity].created)).toUTCString();
    }

    self['activities'] = data.entities;

    if (typeof(callback) === 'function') {
      callback(err, data, data.entities);
    }
  });

}

Usergrid.Entity.prototype.getFollowing = function (callback) {

  var self = this;

  var endpoint = 'users' + '/' + this.get('uuid') + '/following' ;
  var options = {
    method:'GET',
    endpoint:endpoint
  };
  this._client.request(options, function (err, data) {
    if (err && self._client.logging) {
      console.log('could not get user following');
    }

    for(entity in data.entities) {
      data.entities[entity].createdDate = (new Date(data.entities[entity].created)).toUTCString();
      var image = self._client.getDisplayImage(data.entities[entity].email, data.entities[entity].picture);
      data.entities[entity]._portal_image_icon =  image;
    }

    self['following'] = data.entities;

    if (typeof(callback) === 'function') {
      callback(err, data, data.entities);
    }
  });

}


Usergrid.Entity.prototype.getFollowers = function (callback) {

  var self = this;

  var endpoint = 'users' + '/' + this.get('uuid') + '/followers' ;
  var options = {
    method:'GET',
    endpoint:endpoint
  };
  this._client.request(options, function (err, data) {
    if (err && self._client.logging) {
      console.log('could not get user followers');
    }

    for(entity in data.entities) {
      data.entities[entity].createdDate = (new Date(data.entities[entity].created)).toUTCString();
      var image = self._client.getDisplayImage(data.entities[entity].email, data.entities[entity].picture);
      data.entities[entity]._portal_image_icon =  image;
    }

    self['followers'] = data.entities;

    if (typeof(callback) === 'function') {
      callback(err, data, data.entities);
    }
  });

}

Usergrid.Entity.prototype.getRoles = function (callback) {

  var self = this;

  var endpoint = this.get('type') + '/' + this.get('uuid') + '/roles' ;
  var options = {
    method:'GET',
    endpoint:endpoint
  };
  this._client.request(options, function (err, data) {
    if (err && self._client.logging) {
      console.log('could not get user roles');
    }

    self['roles'] = data.entities;

    if (typeof(callback) === 'function') {
      callback(err, data, data.entities);
    }
  });

}

Usergrid.Entity.prototype.getPermissions = function (callback) {

  var self = this;

  var endpoint = this.get('type') + '/' + this.get('uuid') + '/permissions' ;
  var options = {
    method:'GET',
    endpoint:endpoint
  };
  this._client.request(options, function (err, data) {
    if (err && self._client.logging) {
      console.log('could not get user permissions');
    }

    var permissions = [];
    if (data.data) {
      var perms = data.data;
      var count = 0;

      for (var i in perms) {
        count++;
        var perm = perms[i];
        var parts = perm.split(':');
        var ops_part = "";
        var path_part = parts[0];

        if (parts.length > 1) {
          ops_part = parts[0];
          path_part = parts[1];
        }

        ops_part.replace("*", "get,post,put,delete")
        var ops = ops_part.split(',');
        var ops_object = {}
        ops_object['get'] = 'no';
        ops_object['post'] = 'no';
        ops_object['put'] = 'no';
        ops_object['delete'] = 'no';
        for (var j in ops) {
          ops_object[ops[j]] = 'yes';
        }

        permissions.push( {operations : ops_object, path : path_part, perm : perm});
      }
    }

    self['permissions'] = permissions;

    if (typeof(callback) === 'function') {
      callback(err, data, data.entities);
    }
  });

}

/*
*  disconnects one entity from another
*
*  @method disconnect
*  @public
*  @param {string} connection
*  @param {object} entity
*  @param {function} callback
*  @return {callback} callback(err, data)
*
*/
Usergrid.Entity.prototype.disconnect = function (connection, entity, callback) {

  var self = this;

  //connectee info
  var connecteeType = entity.get('type');
  var connectee = this.getEntityId(entity);
  if (!connectee) {
    if (typeof(callback) === 'function') {
      var error = 'Error trying to delete object - no uuid specified.';
      if (self._client.logging) {
        console.log(error);
      }
      callback(true, error);
    }
    return;
  }

  //connector info
  var connectorType = this.get('type');
  var connector = this.getEntityId(this);
  if (!connector) {
    if (typeof(callback) === 'function') {
      var error = 'Error in connect - no uuid specified.';
      if (self._client.logging) {
        console.log(error);
      }
      callback(true, error);
    }
    return;
  }

  var endpoint = connectorType + '/' + connector + '/' + connection + '/' + connecteeType + '/' + connectee;
  var options = {
    method:'DELETE',
    endpoint:endpoint
  };
  this._client.request(options, function (err, data) {
    if (err && self._client.logging) {
      console.log('entity could not be disconnected');
    }
    if (typeof(callback) === 'function') {
      callback(err, data);
    }
  });
}

/*
*  The Collection class models Usergrid Collections.  It essentially
*  acts as a container for holding Entity objects, while providing
*  additional funcitonality such as paging, and saving
*
*  @constructor
*  @param {string} options - configuration object
*  @param {function} callback
*  @return {callback} callback(err, data)
*/
Usergrid.Collection = function(options, callback) {

  if (options) {
    this._client = options.client;
    this._type = options.type;
    this.qs = options.qs || {};

    //iteration
    this._list = options.list || [];
    this._iterator = options.iterator || -1; //first thing we do is increment, so set to -1

    //paging
    this._previous = options.previous || [];
    this._next = options.next || null;
    this._cursor = options.cursor || null;

    //restore entities if available
    if (options.list) {
      var count = options.list.length;
      for(var i=0;i<count;i++){
        //make new entity with
        var entity = this._client.restoreEntity(options.list[i]);
        this._list[i] = entity;
      }
    }
  }
  if (callback) {
    //populate the collection
    this.fetch(callback);
  }

}


/*
 *  gets the data from the collection object for serialization
 *
 *  @method serialize
 *  @return {object} data
 */
Usergrid.Collection.prototype.serialize = function () {

  //pull out the state from this object and return it
  var data = {}
  data.type = this._type;
  data.qs = this.qs;
  data.iterator = this._iterator;
  data.previous = this._previous;
  data.next = this._next;
  data.cursor = this._cursor;

  this.resetEntityPointer();
  var i=0;
  data.list = [];
  while(this.hasNextEntity()) {
    var entity = this.getNextEntity();
    data.list[i] = entity.serialize();
    i++;
  }

  data = JSON.stringify(data);
  return data;
}

Usergrid.Collection.prototype.addCollection = function (collectionName, options, callback) {
  self = this;
  options.client = this._client;
  var collection = new Usergrid.Collection(options, function(err, data) {
    if (typeof(callback) === 'function') {

      collection.resetEntityPointer();
      while(collection.hasNextEntity()) {
        var user = collection.getNextEntity();
        var email = user.get('email');
        var image = self._client.getDisplayImage(user.get('email'), user.get('picture'));
        user._portal_image_icon = image;
      }

      self[collectionName] = collection;
      callback(err, collection);
    }
  });
}

/*
*  Populates the collection from the server
*
*  @method fetch
*  @param {function} callback
*  @return {callback} callback(err, data)
*/
Usergrid.Collection.prototype.fetch = function (callback) {
  var self = this;
  var qs = this.qs;

  //add in the cursor if one is available
  if (this._cursor) {
    qs.cursor = this._cursor;
  } else {
    delete qs.cursor;
  }
  var options = {
    method:'GET',
    endpoint:this._type,
    qs:this.qs
  };
  this._client.request(options, function (err, data) {
    if(err && self._client.logging) {
     console.log('error getting collection');
    } else {
      //save the cursor if there is one
      var cursor = data.cursor || null;
      self.saveCursor(cursor);
      if (data.entities) {
        self.resetEntityPointer();
        var count = data.entities.length;
        //save entities locally
        self._list = []; //clear the local list first
        for (var i=0;i<count;i++) {
          var uuid = data.entities[i].uuid;
          if (uuid) {
            var entityData = data.entities[i] || {};
            self._baseType = data.entities[i].type; //store the base type in the collection
            entityData.type = self._type;//make sure entities are same type (have same path) as parent collection.
            var entityOptions = {
              client:self._client,
              data:entityData
            };

            var ent = new Usergrid.Entity(entityOptions);
            ent._json = JSON.stringify(entityData, null, 2);
            //if this is a user, add in an icon image
            if (self._type === 'users' || self._type ==='user' || data.entities[i].type == 'user') {
              var email = entityData.email;
              var picture = entityData.picture;
              var image = self._client.getDisplayImage(email, picture);
              ent._portal_image_icon = image;
            }
            var ct = self._list.length;
            self._list[ct] = ent;
          }
        }
      }
    }
    if (typeof(callback) === 'function') {
      callback(err, data);
    }
  });
}

/*
*  Adds a new Entity to the collection (saves, then adds to the local object)
*
*  @method addNewEntity
*  @param {object} entity
*  @param {function} callback
*  @return {callback} callback(err, data, entity)
*/
Usergrid.Collection.prototype.addEntity = function (options, callback) {
  var self = this;
  options.type = this._type;

  //create the new entity
  this._client.createEntity(options, function (err, entity) {

    if (err) {
      if (typeof(callback) === 'function') {
        callback(err, entity);
      }
    } else {

      if (entity.type === '/users') {
        var image = self._client.getDisplayImage(entity.email, entity.picture);
        entity._portal_image_icon = image;
      }

      if (!err) {
        //then add the entity to the list
        var count = self._list.length;
        self._list[count] = entity;
      }
      if (typeof(callback) === 'function') {
        callback(err, entity);
      }
    }
  });
}

Usergrid.Collection.prototype.addExistingEntity = function (entity) {
  //entity should already exist in the db, so just add it to the list
  var count = this._list.length;
  this._list[count] = entity;
}


/*
*  Removes the Entity from the collection, then destroys the object on the server
*
*  @method destroyEntity
*  @param {object} entity
*  @param {function} callback
*  @return {callback} callback(err, data)
*/
Usergrid.Collection.prototype.destroyEntity = function (entity, callback) {
  var self = this;
  entity.destroy(function(err, data) {
    if (err) {
      if (self._client.logging) {
        console.log('could not destroy entity');
      }
      if (typeof(callback) === 'function') {
        callback(err, data);
      }
    } else {
      //destroy was good, so repopulate the collection
      self.fetch(callback);
    }
  });
  //remove entity from the local store
  this.removeEntity(entity);
}


Usergrid.Collection.prototype.removeEntity = function (entity) {
  var uuid = entity.get('uuid');
  for (key in this._list) {
    var listItem = this._list[key];
    if (listItem.get('uuid') === uuid) {
      return this._list.splice(key, 1);
    }
  }
  return false;
}

/*
*  Looks up an Entity by UUID
*
*  @method getEntityByUUID
*  @param {string} UUID
*  @param {function} callback
*  @return {callback} callback(err, data, entity)
*/
Usergrid.Collection.prototype.getEntityByUUID = function (uuid, callback) {

  for (key in this._list) {
    var listItem = this._list[key];
    if (listItem.get('uuid') === uuid) {
      return listItem;
    }
  }

  //get the entity from the database
  var options = {
    data: {
      type: this._type,
      uuid:uuid
    },
    client: this._client
  }
  var entity = new Usergrid.Entity(options);
  entity.fetch(callback);
}

/*
*  Returns the first Entity of the Entity list - does not affect the iterator
*
*  @method getFirstEntity
*  @return {object} returns an entity object
*/
Usergrid.Collection.prototype.getFirstEntity = function () {
  var count = this._list.length;
  if (count > 0) {
    return this._list[0];
  }
  return null;
}

/*
*  Returns the last Entity of the Entity list - does not affect the iterator
*
*  @method getLastEntity
*  @return {object} returns an entity object
*/
Usergrid.Collection.prototype.getLastEntity = function () {
  var count = this._list.length;
  if (count > 0) {
    return this._list[count-1];
  }
  return null;
}

/*
*  Entity iteration -Checks to see if there is a "next" entity
*  in the list.  The first time this method is called on an entity
*  list, or after the resetEntityPointer method is called, it will
*  return true referencing the first entity in the list
*
*  @method hasNextEntity
*  @return {boolean} true if there is a next entity, false if not
*/
Usergrid.Collection.prototype.hasNextEntity = function () {
  var next = this._iterator + 1;
  var hasNextElement = (next >=0 && next < this._list.length);
  if(hasNextElement) {
    return true;
  }
  return false;
}

/*
*  Entity iteration - Gets the "next" entity in the list.  The first
*  time this method is called on an entity list, or after the method
*  resetEntityPointer is called, it will return the,
*  first entity in the list
*
*  @method hasNextEntity
*  @return {object} entity
*/
Usergrid.Collection.prototype.getNextEntity = function () {
  this._iterator++;
  var hasNextElement = (this._iterator >= 0 && this._iterator <= this._list.length);
  if(hasNextElement) {
    return this._list[this._iterator];
  }
  return false;
}

/*
*  Entity iteration - Checks to see if there is a "previous"
*  entity in the list.
*
*  @method hasPrevEntity
*  @return {boolean} true if there is a previous entity, false if not
*/
Usergrid.Collection.prototype.hasPrevEntity = function () {
  var previous = this._iterator - 1;
  var hasPreviousElement = (previous >=0 && previous < this._list.length);
  if(hasPreviousElement) {
    return true;
  }
  return false;
}

/*
*  Entity iteration - Gets the "previous" entity in the list.
*
*  @method getPrevEntity
*  @return {object} entity
*/
Usergrid.Collection.prototype.getPrevEntity = function () {
   this._iterator--;
   var hasPreviousElement = (this._iterator >= 0 && this._iterator <= this._list.length);
   if(hasPreviousElement) {
    return this.list[this._iterator];
   }
   return false;
}

/*
*  Entity iteration - Resets the iterator back to the beginning
*  of the list
*
*  @method resetEntityPointer
*  @return none
*/
Usergrid.Collection.prototype.resetEntityPointer = function () {
   this._iterator  = -1;
}

/*
* Method to save off the cursor just returned by the last API call
*
* @public
* @method saveCursor
* @return none
*/
Usergrid.Collection.prototype.saveCursor = function(cursor) {
  //if current cursor is different, grab it for next cursor
  if (this._next !== cursor) {
    this._next = cursor;
  }
}

/*
* Resets the paging pointer (back to original page)
*
* @public
* @method resetPaging
* @return none
*/
Usergrid.Collection.prototype.resetPaging = function() {
  this._previous = [];
  this._next = null;
  this._cursor = null;
}

/*
*  Paging -  checks to see if there is a next page od data
*
*  @method hasNextPage
*  @return {boolean} returns true if there is a next page of data, false otherwise
*/
Usergrid.Collection.prototype.hasNextPage = function () {
  return (this._next);
}

/*
*  Paging - advances the cursor and gets the next
*  page of data from the API.  Stores returned entities
*  in the Entity list.
*
*  @method getNextPage
*  @param {function} callback
*  @return {callback} callback(err, data)
*/
Usergrid.Collection.prototype.getNextPage = function (callback) {
  if (this.hasNextPage()) {
    //set the cursor to the next page of data
    this._previous.push(this._cursor);
    this._cursor = this._next;
    //empty the list
    this._list = [];
    this.fetch(callback);
  }
}

/*
*  Paging -  checks to see if there is a previous page od data
*
*  @method hasPreviousPage
*  @return {boolean} returns true if there is a previous page of data, false otherwise
*/
Usergrid.Collection.prototype.hasPreviousPage = function () {
  return (this._previous.length > 0);
}

/*
*  Paging - reverts the cursor and gets the previous
*  page of data from the API.  Stores returned entities
*  in the Entity list.
*
*  @method getPreviousPage
*  @param {function} callback
*  @return {callback} callback(err, data)
*/
Usergrid.Collection.prototype.getPreviousPage = function (callback) {
  if (this.hasPreviousPage()) {
    this._next=null; //clear out next so the comparison will find the next item
    this._cursor = this._previous.pop();
    //empty the list
    this._list = [];
    this.fetch(callback);
  }
}


/*
 *  A class to model a Usergrid group.
 *  Set the path in the options object.
 *
 *  @constructor
 *  @param {object} options {client:client, data: {'key': 'value'}, path:'path'}
 */
Usergrid.Group = function(options, callback) {
  this._path = options.path;
  this._list = [];
  this._client = options.client;
  this._data = options.data || {};
  this._data.type = "groups";
}

/*
 *  Inherit from Usergrid.Entity.
 *  Note: This only accounts for data on the group object itself.
 *  You need to use add and remove to manipulate group membership.
 */
Usergrid.Group.prototype = new Usergrid.Entity();

/*
*  Fetches current group data, and members.
*
*  @method fetch
*  @public
*  @param {function} callback
*  @returns {function} callback(err, data)
*/
Usergrid.Group.prototype.fetch = function(callback) {
  var self = this;
  var groupEndpoint = 'groups/'+this._path;
  var memberEndpoint = 'groups/'+this._path+'/users';

  var groupOptions = {
    method:'GET',
    endpoint:groupEndpoint
  }

  var memberOptions = {
    method:'GET',
    endpoint:memberEndpoint
  }

  this._client.request(groupOptions, function(err, data){
    if(err) {
      if(self._client.logging) {
        console.log('error getting group');
      }
      if(typeof(callback) === 'function') {
        callback(err, data);
      }
    } else {
      if(data.entities) {
        var groupData = data.entities[0];
        self._data = groupData || {};
        self._client.request(memberOptions, function(err, data) {
          if(err && self._client.logging) {
            console.log('error getting group users');
          } else {
            if(data.entities) {
              var count = data.entities.length;
              self._list = [];
              for (var i = 0; i < count; i++) {
                var uuid = data.entities[i].uuid;
                if(uuid) {
                  var entityData = data.entities[i] || {};
                  var entityOptions = {
                    type: entityData.type,
                    client: self._client,
                    uuid:uuid,
                    data:entityData
                  };
                  var entity = new Usergrid.Entity(entityOptions);
                  self._list.push(entity);
                }

              }
            }
          }
          if(typeof(callback) === 'function') {
            callback(err, data, self._list);
          }
        });
      }
    }
  });
}

/*
 *  Retrieves the members of a group.
 *
 *  @method members
 *  @public
 *  @param {function} callback
 *  @return {function} callback(err, data);
 */
Usergrid.Group.prototype.members = function(callback) {
  if(typeof(callback) === 'function') {
    callback(null, this._list);
  }
}

/*
 *  Adds a user to the group, and refreshes the group object.
 *
 *  Options object: {user: user_entity}
 *
 *  @method add
 *  @public
 *  @params {object} options
 *  @param {function} callback
 *  @return {function} callback(err, data)
 */
Usergrid.Group.prototype.add = function(options, callback) {
  var self = this;
  var options = {
    method:"POST",
    endpoint:"groups/"+this._path+"/users/"+options.user.get('username')
  }

  this._client.request(options, function(error, data){
    if(error) {
      if(typeof(callback) === 'function') {
        callback(error, data, data.entities);
      }
    } else {
      self.fetch(callback);
    }
  });
}

/*
 *  Removes a user from a group, and refreshes the group object.
 *
 *  Options object: {user: user_entity}
 *
 *  @method remove
 *  @public
 *  @params {object} options
 *  @param {function} callback
 *  @return {function} callback(err, data)
 */
Usergrid.Group.prototype.remove = function(options, callback) {
  var self = this;

  var options = {
    method:"DELETE",
    endpoint:"groups/"+this._path+"/users/"+options.user.get('username')
  }

  this._client.request(options, function(error, data){
    if(error) {
      if(typeof(callback) === 'function') {
        callback(error, data);
      }
    } else {
      self.fetch(callback);
    }
  });
}

/*
* Gets feed for a group.
*
* @public
* @method feed
* @param {function} callback
* @returns {callback} callback(err, data, activities)
*/
Usergrid.Group.prototype.feed = function(callback) {
  var self = this;

  var endpoint = "groups/"+this._path+"/feed";

  var options = {
    method:"GET",
    endpoint:endpoint
  }

  this._client.request(options, function(err, data){
    if (err && self.logging) {
      console.log('error trying to log user in');
    }
    if(typeof(callback) === 'function') {
        callback(err, data, data.entities);
    }
  });
}

/*
* Creates activity and posts to group feed.
*
* options object: {user: user_entity, content: "activity content"}
*
* @public
* @method createGroupActivity
* @params {object} options
* @param {function} callback
* @returns {callback} callback(err, entity)
*/
Usergrid.Group.prototype.createGroupActivity = function(options, callback){
  var user = options.user;
  var options = {
    actor: {
      "displayName":user.get("username"),
      "uuid":user.get("uuid"),
      "username":user.get("username"),
      "email":user.get("email"),
      "picture":user.get("picture"),
      "image": {
        "duration":0,
        "height":80,
        "url":user.get("picture"),
        "width":80
       },
    },
    "verb":"post",
    "content":options.content };

    options.type = 'groups/'+this._path+'/activities';
    var options = {
      client:this._client,
      data:options
    }

    var entity = new Usergrid.Entity(options);
    entity.save(function(err, data) {
      if (typeof(callback) === 'function') {
        callback(err, entity);
      }
    });
}

/*
* Tests if the string is a uuid
*
* @public
* @method isUUID
* @param {string} uuid The string to test
* @returns {Boolean} true if string is uuid
*/
function isUUID (uuid) {
  var uuidValueRegex = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
  if (!uuid) return false;
  return uuidValueRegex.test(uuid);
}

/*
*  method to encode the query string parameters
*
*  @method encodeParams
*  @public
*  @params {object} params - an object of name value pairs that will be urlencoded
*  @return {string} Returns the encoded string
*/
function encodeParams (params) {
  tail = [];
  var item = [];
  if (params instanceof Array) {
    for (i in params) {
      item = params[i];
      if ((item instanceof Array) && (item.length > 1)) {
        tail.push(item[0] + "=" + encodeURIComponent(item[1]));
      }
    }
  } else {
    for (var key in params) {
      if (params.hasOwnProperty(key)) {
        var value = params[key];
        if (value instanceof Array) {
          for (i in value) {
            item = value[i];
            tail.push(key + "=" + encodeURIComponent(item));
          }
        } else {
          tail.push(key + "=" + encodeURIComponent(value));
        }
      }
    }
  }
  return tail.join("&");
}

})(window,sessionStorage);
