text: /* globals OAuth*/
  import s from 'underscore.string';
  
  // Request custom OAuth credentials for the user
  // @param options {optional}
  // @param credentialRequestCompleteCallback {Function} Callback function to call on
  //   completion. Takes one argument, credentialToken on success, or Error on
  //   error.
  
  export class CustomOAuth {
  	constructor(name, options) {
  		this.name = name;
  		if (!Match.test(this.name, String)) {
  			throw new Meteor.Error('CustomOAuth: Name is required and must be String');
  		}
  
  		this.configure(options);
  
  		Accounts.oauth.registerService(this.name);
  
  		this.configureLogin();
  	}
  
  	configure(options) {
  		if (!Match.test(options, Object)) {
  			throw new Meteor.Error('CustomOAuth: Options is required and must be Object');
  		}
  
  		if (!Match.test(options.serverURL, String)) {
  			throw new Meteor.Error('CustomOAuth: Options.serverURL is required and must be String');
  		}
  
  		if (!Match.test(options.authorizePath, String)) {
  			options.authorizePath = '/oauth/authorize';
  		}
  
  		if (!Match.test(options.scope, String)) {
  			options.scope = 'openid';
  		}
  
  		this.serverURL = options.serverURL;
  		this.authorizePath = options.authorizePath;
  		this.scope = options.scope;
  
  		if (!/^https?:\/\/.+/.test(this.authorizePath)) {
  			this.authorizePath = this.serverURL + this.authorizePath;
  		}
  	}
  
  	configureLogin() {
  		const loginWithService = `loginWith${ s.capitalize(this.name) }`;
  
  		Meteor[loginWithService] = (options, callback) => {
  			// support a callback without options
  			if (!callback && typeof options === 'function') {
  				callback = options;
  				options = null;
  			}
  
  			const credentialRequestCompleteCallback = Accounts.oauth.credentialRequestCompleteHandler(callback);
  			this.requestCredential(options, credentialRequestCompleteCallback);
  		};
  	}
  
  	requestCredential(options, credentialRequestCompleteCallback) {
  		// support both (options, callback) and (callback).
  		if (!credentialRequestCompleteCallback && typeof options === 'function') {
  			credentialRequestCompleteCallback = options;
  			options = {};
  		}
  
  		const config = ServiceConfiguration.configurations.findOne({ service: this.name });
  		if (!config) {
  			if (credentialRequestCompleteCallback) {
  				credentialRequestCompleteCallback(new ServiceConfiguration.ConfigError());
  			}
  			return;
  		}
  
  		const credentialToken = Random.secret();
  		const loginStyle = OAuth._loginStyle(this.name, config, options);
  
  		const separator = this.authorizePath.indexOf('?') !== -1 ? '&' : '?';
  
  		const loginUrl = `${ this.authorizePath
  		}${ separator }client_id=${ config.clientId
  		}&redirect_uri=${ OAuth._redirectUri(this.name, config)
  		}&response_type=code` +
  			`&state=${ OAuth._stateParam(loginStyle, credentialToken, options.redirectUrl)
  			}&scope=${ this.scope }`;
  
  		OAuth.launchLogin({
  			loginService: this.name,
  			loginStyle,
  			loginUrl,
  			credentialRequestCompleteCallback,
  			credentialToken,
  			popupOptions: {
  				width: 900,
  				height: 450,
  			},
  		});
  	}
  }
  