"use strict";
var _Object$defineProperty = require("@babel/runtime-corejs3/core-js-stable/object/define-property");
var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
_Object$defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _ParseUser = _interopRequireDefault(require("./ParseUser"));
/**
 * @flow-weak
 */
/* global FB */
var initialized = false;
var requestedPermissions;
var initOptions;
var provider = {
  authenticate: function (options) {
    var _this = this;
    if (typeof FB === 'undefined') {
      options.error(this, 'Facebook SDK not found.');
    }
    FB.login(function (response) {
      if (response.authResponse) {
        if (options.success) {
          options.success(_this, {
            id: response.authResponse.userID,
            access_token: response.authResponse.accessToken,
            expiration_date: new Date(response.authResponse.expiresIn * 1000 + new Date().getTime()).toJSON()
          });
        }
      } else {
        if (options.error) {
          options.error(_this, response);
        }
      }
    }, {
      scope: requestedPermissions
    });
  },
  restoreAuthentication: function (authData) {
    if (authData) {
      var newOptions = {};
      if (initOptions) {
        for (var key in initOptions) {
          newOptions[key] = initOptions[key];
        }
      }
      // Suppress checks for login status from the browser.
      newOptions.status = false;
      // If the user doesn't match the one known by the FB SDK, log out.
      // Most of the time, the users will match -- it's only in cases where
      // the FB SDK knows of a different user than the one being restored
      // from a Parse User that logged in with username/password.
      var existingResponse = FB.getAuthResponse();
      if (existingResponse && existingResponse.userID !== authData.id) {
        FB.logout();
      }
      FB.init(newOptions);
    }
    return true;
  },
  getAuthType: function () {
    return 'facebook';
  },
  deauthenticate: function () {
    this.restoreAuthentication(null);
  }
};
/**
 * Provides a set of utilities for using Parse with Facebook.
 *
 * @class Parse.FacebookUtils
 * @static
 * @hideconstructor
 */
var FacebookUtils = {
  /**
   * Initializes Parse Facebook integration.  Call this function after you
   * have loaded the Facebook Javascript SDK with the same parameters
   * as you would pass to
   * 
   * FB.init().  Parse.FacebookUtils will invoke FB.init() for you
   * with these arguments.
   *
   * @function init
   * @name Parse.FacebookUtils.init
   * @param {object} options Facebook options argument as described here:
   *   
   *   FB.init(). The status flag will be coerced to 'false' because it
   *   interferes with Parse Facebook integration. Call FB.getLoginStatus()
   *   explicitly if this behavior is required by your application.
   */
  init: function (options) {
    if (typeof FB === 'undefined') {
      throw new Error('The Facebook JavaScript SDK must be loaded before calling init.');
    }
    initOptions = {};
    if (options) {
      for (var key in options) {
        initOptions[key] = options[key];
      }
    }
    if (initOptions.status && typeof console !== 'undefined') {
      var warn = console.warn || console.log || function () {}; // eslint-disable-line no-console
      warn.call(console, 'The "status" flag passed into' + ' FB.init, when set to true, can interfere with Parse Facebook' + ' integration, so it has been suppressed. Please call' + ' FB.getLoginStatus() explicitly if you require this behavior.');
    }
    initOptions.status = false;
    FB.init(initOptions);
    _ParseUser.default._registerAuthenticationProvider(provider);
    initialized = true;
  },
  /**
   * Gets whether the user has their account linked to Facebook.
   *
   * @function isLinked
   * @name Parse.FacebookUtils.isLinked
   * @param {Parse.User} user User to check for a facebook link.
   *     The user must be logged in on this device.
   * @returns {boolean} true if the user has their account
   *     linked to Facebook.
   */
  isLinked: function (user) {
    return user._isLinked('facebook');
  },
  /**
   * Logs in a user using Facebook. This method delegates to the Facebook
   * SDK to authenticate the user, and then automatically logs in (or
   * creates, in the case where it is a new user) a Parse.User.
   *
   * Standard API:
   *
   * logIn(permission: string, authData: Object);
   *
   * Advanced API: Used for handling your own oAuth tokens
   * {@link https://docs.parseplatform.org/rest/guide/#linking-users}
   *
   * logIn(authData: Object, options?: Object);
   *
   * @function logIn
   * @name Parse.FacebookUtils.logIn
   * @param {(string | object)} permissions The permissions required for Facebook
   *    log in.  This is a comma-separated string of permissions.
   *    Alternatively, supply a Facebook authData object as described in our
   *    REST API docs if you want to handle getting facebook auth tokens
   *    yourself.
   * @param {object} options MasterKey / SessionToken. Alternatively can be used for authData if permissions is a string
   * @returns {Promise}
   */
  logIn: function (permissions, options) {
    if (!permissions || typeof permissions === 'string') {
      if (!initialized) {
        throw new Error('You must initialize FacebookUtils before calling logIn.');
      }
      requestedPermissions = permissions;
      return _ParseUser.default.logInWith('facebook', options);
    }
    return _ParseUser.default.logInWith('facebook', {
      authData: permissions
    }, options);
  },
  /**
   * Links Facebook to an existing PFUser. This method delegates to the
   * Facebook SDK to authenticate the user, and then automatically links
   * the account to the Parse.User.
   *
   * Standard API:
   *
   * link(user: Parse.User, permission: string, authData?: Object);
   *
   * Advanced API: Used for handling your own oAuth tokens
   * {@link https://docs.parseplatform.org/rest/guide/#linking-users}
   *
   * link(user: Parse.User, authData: Object, options?: FullOptions);
   *
   * @function link
   * @name Parse.FacebookUtils.link
   * @param {Parse.User} user User to link to Facebook. This must be the
   *     current user.
   * @param {(string | object)} permissions The permissions required for Facebook
   *    log in.  This is a comma-separated string of permissions.
   *    Alternatively, supply a Facebook authData object as described in our
   *    REST API docs if you want to handle getting facebook auth tokens
   *    yourself.
   * @param {object} options MasterKey / SessionToken. Alternatively can be used for authData if permissions is a string
   * @returns {Promise}
   */
  link: function (user, permissions, options) {
    if (!permissions || typeof permissions === 'string') {
      if (!initialized) {
        throw new Error('You must initialize FacebookUtils before calling link.');
      }
      requestedPermissions = permissions;
      return user.linkWith('facebook', options);
    }
    return user.linkWith('facebook', {
      authData: permissions
    }, options);
  },
  /**
   * Unlinks the Parse.User from a Facebook account.
   *
   * @function unlink
   * @name Parse.FacebookUtils.unlink
   * @param {Parse.User} user User to unlink from Facebook. This must be the
   *     current user.
   * @param {object} options Standard options object with success and error
   *    callbacks.
   * @returns {Promise}
   */
  unlink: function (user, options) {
    if (!initialized) {
      throw new Error('You must initialize FacebookUtils before calling unlink.');
    }
    return user._unlinkFrom('facebook', options);
  },
  // Used for testing purposes
  _getAuthProvider: function () {
    return provider;
  }
};
var _default = FacebookUtils;
exports.default = _default;