"use strict";
/**
 * @fileoverview An Anonymous Box API Session.
 */
Object.defineProperty(exports, "__esModule", { value: true });
// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------
const bluebird_1 = require("bluebird");
// ------------------------------------------------------------------------------
// Private
// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------
// Public
// ------------------------------------------------------------------------------
/**
 * The Client Credentials Grant Box API Session.
 *
 * The Client Credentials Grant API Session holds a Client Credentials accessToken, which it
 * returns to the client so that it may make calls on behalf of service account or specified users.
 *
 * Tokens will be refreshed in the background if a request is made within the
 * "stale buffer" (defaults to 10 minutes before the token is set to expire).
 * If the token is also expired, all incoming requests will be held until a fresh token
 * is retrieved.
 *
 * @param {Config} config The SDK configuration options
 * @param {TokenManager} tokenManager The TokenManager
 * @constructor
 */
class CCGSession {
    constructor(config, tokenManager) {
        this._config = config;
        this._tokenManager = tokenManager;
        // The TokenInfo object for this anonymous session
        this._tokenInfo = null;
        this._refreshPromise = null;
    }
    /**
     * Initiate a refresh of the access tokens. New tokens should be passed to the
     * caller, and then cached for later use.
     *
     * @param {?TokenRequestOptions} [options] - Sets optional behavior for the token grant
     * @returns {Promise<string>} Promise resolving to the access token
     * @private
     */
    _refreshAccessToken(options) {
        // If tokens aren't already being refreshed, start the refresh
        if (!this._refreshPromise) {
            // Initiate a refresh
            this._refreshPromise = this._tokenManager
                .getTokensClientCredentialsGrant(options)
                .then((tokenInfo) => {
                // Set new token info and propagate the new access token
                this._tokenInfo = tokenInfo;
                return tokenInfo.accessToken;
            })
                .finally(() => {
                // Refresh complete, clear promise
                this._refreshPromise = null;
            });
        }
        return this._refreshPromise;
    }
    /**
     * Produces a valid, anonymous access token.
     * Performs a refresh before returning if the current token is expired. If the current
     * token is considered stale but still valid, return the current token but initiate a
     * new refresh in the background.
     *
     * @param {TokenRequestOptions} [options] - Sets optional behavior for the token grant
     * @returns {Promise<string>} Promise resolving to the access token
     */
    getAccessToken(options) {
        // If the current token is no longer fresh, get a new token. All incoming
        // requests will be held until a fresh token is retrieved.
        var expirationBuffer = this._config.expiredBufferMS;
        if (!this._tokenInfo ||
            !this._tokenManager.isAccessTokenValid(this._tokenInfo, expirationBuffer)) {
            return this._refreshAccessToken(options);
        }
        // Your token is not currently stale! Return the current access token.
        return bluebird_1.Promise.resolve(this._tokenInfo.accessToken);
    }
    /**
     * Revokes the anonymous token used by this anonymous session, and clears the saved tokenInfo.
     *
     * @param {TokenRequestOptions} [options] - Sets optional behavior for the token grant
     * @returns {Promise} Promise resolving if the revoke succeeds
     */
    revokeTokens(options) {
        // The current anonymous token is revoked (but a new one will be created automatically as needed).
        var tokenInfo = this._tokenInfo || {}, accessToken = tokenInfo.accessToken;
        this._tokenInfo = null;
        return this._tokenManager.revokeTokens(accessToken, options);
    }
    /**
     * Exchange the client access token for one with lower scope
     *
     * @param {string|string[]} scopes The scope(s) requested for the new token
     * @param {string} [resource] The absolute URL of an API resource to scope the new token to
     * @param {Object} [options] - Optional parameters
     * @param {TokenRequestOptions} [options.tokenRequestOptions] - Sets optional behavior for the token grant
     * @returns {void}
     */
    exchangeToken(scopes, resource, options) {
        // We need to get the access token, in case it hasn't been generated yet
        return this.getAccessToken(options).then((accessToken) => this._tokenManager.exchangeToken(accessToken, scopes, resource, options));
    }
}
/**
 * @module box-node-sdk/lib/sessions/ccg-session
 * @see {@Link CCGSession}
 */
exports.default = CCGSession;
//# sourceMappingURL=ccg-session.js.map