/*jshint eqnull:true, browser:true */
/*global console, cookie */
//
// Twitch user-related functions
// Depends on twitch [core, storage, api]
//
// User Data
// ----------
// To access user-specific data used for rendering, register
// a callback which will receive user data upon recipt from the API,
// located at `/api/me` (Api::UserDataController#show)
//
//     Twitch.user(function(info) {
//       // the user is logged in
//       console.log('your display name is', info.display_name);
//     }, function() {
//       // not logged in or api error
//       console.log('sorry, you are not logged in');
//     });
//
// Notes
// -----
// The api_token cookie is used as a sentinel--it is only set by Rails
// so as long as it exists (not expired), we can continue to use the
// cookies managed by JS on each page.


(function (Twitch, $) {
  var _fetchedUser = null;
  var isAuthenticated = null;
  var userData = null;

  function fetchUser() {
    if (_fetchedUser) {
      return _fetchedUser;
    }

    // Update login and display name cookies based on authoritative
    // results from the API
    var COOKIE_EXPIRY = 14; // days

    _fetchedUser = new RSVP.Promise(function (resolve, reject) {
      // Ensure user is logged in
      if (!cookie.get('api_token')) {
        // User no longer has authorization for the api, as this token
        // has expired or been deleted.
        reject({status: 401});
        return;
      }

      var loginApi = function() {
        Twitch.api.get('/api/me')
        .done(function (userData) {
          resolve(userData);
        })
        .fail(function (jqXHR) {
          reject({status: jqXHR.status});
        });
      };

      if (Twitch.api.isIframeReady) {
        loginApi();
      } else {
        Twitch.api.on('ready', loginApi);
      }
    }).then(function (info) {
      cookie.set('login', info.login, {
        expires: COOKIE_EXPIRY
      })
      .set('name', encodeURI(info.name), {
        expires: COOKIE_EXPIRY
      });
      isAuthenticated = true;
      userData = info;
      return info;
    }, function (err) {
      if (err.status === 401) {
        isAuthenticated = false;
        // We're not logged in
        cookie.remove('login');
        cookie.remove('name');
      }
      throw err;
    });

    return _fetchedUser;
  }

  var user = function (success, failure) {
    // success and failure are both optional as per https://promisesaplus.com/#point-23
    return fetchUser().then(success, failure);
  };

  user.login = function () {
    if (!cookie.get('api_token')) return null;

    return cookie.get('login');
  };

  user.displayName = function () {
    if (!cookie.get('api_token')) return null;

    return decodeURI(cookie.get('name'));
  };

  user.isLoggedIn = function () {
    if (!cookie.get('api_token')) return false;

    return !!cookie.get('login');
  };

  /*
   * Peek at the current authentication state and userData without starting
   * authentication. web-client uses this to avoid using Twitch.user and the
   * resulting non-Ember RSVP promise is possible.
   */
  user.peek = function () {
    return {
      isAuthenticated: isAuthenticated,
      userData: userData
    };
  };

  user.reset = function () {
    _fetchedUser = undefined;
    isAuthenticated = null;
    userData = null;
  };

  // Legacy Functions:
  // These access PP directly and are synchronous, so avoid and use
  // Twitch.user(fn) instead (see top of this file for details)
  var DEPRECATED = "Deprecation warning: Use Twitch.user() instead";

  user.userId = function () {
    console.debug(DEPRECATED);
    return PP.user_id;
  };

  Twitch.mixin({
    user: user
  });

})(Twitch, jQuery);
