/* globals Google */
import _ from 'underscore';

function getIdentity(accessToken) {
	try {
		return HTTP.get(
			'https://www.googleapis.com/oauth2/v1/userinfo',
			{ params: { access_token: accessToken } }).data;
	} catch (err) {
		throw _.extend(new Error(`Failed to fetch identity from Google. ${ err.message }`), { response: err.response });
	}
}

function getScopes(accessToken) {
	try {
		return HTTP.get(
			'https://www.googleapis.com/oauth2/v1/tokeninfo',
			{ params: { access_token: accessToken } }).data.scope.split(' ');
	} catch (err) {
		throw _.extend(new Error(`Failed to fetch tokeninfo from Google. ${ err.message }`), { response: err.response });
	}
}


RocketChat.registerAccessTokenService('google', function(options) {
	check(options, Match.ObjectIncluding({
		accessToken: String,
		idToken: String,
		expiresIn: Match.Integer,
		scope: Match.Maybe(String),
		identity: Match.Maybe(Object),
	}));

	const identity = options.identity || getIdentity(options.accessToken);

	const serviceData = {
		accessToken: options.accessToken,
		idToken: options.idToken,
		expiresAt: (+new Date) + (1000 * parseInt(options.expiresIn, 10)),
		scope: options.scopes || getScopes(options.accessToken),
	};

	const fields = _.pick(identity, Google.whitelistedFields);
	_.extend(serviceData, fields);

	// only set the token in serviceData if it's there. this ensures
	// that we don't lose old ones (since we only get this on the first
	// log in attempt)
	if (options.refreshToken) {
		serviceData.refreshToken = options.refreshToken;
	}

	return {
		serviceData,
		options: {
			profile: {
				name: identity.name,
			},
		},
	};
});
