import Base from 'ember-simple-auth/authenticators/base';
import {inject as injectService} from '@ember/service';

/**
 * This authenticator is used by Ember-Simple-Auth to authenticate
 * a user on the client.
 *
 * Example Usage:
 *
 * ```javascript
 * import Ember from 'ember';
 *
 * export default Ember.Object.extend({
 *     session: Ember.inject.service(),
 *
 *     login(username, password) {
 *         let session = this.get('session');
 *
 *         session.authenticate('authenticator:group-control', username, password);
 *     }
 * });
 * ```
 *
 * To extend in an application:
 *
 * ```javascript
 * import GCAuthenticator from '@bennerinformatics/ember-fw-gc/authenticators/group-control';
 *
 * export default GCAuthenticator.extend({
 *     // ... your custom code here
 * });
 * ```
 *
 * For more example on using this in an application or extending it,
 * visit Ember Simple Auth's [website](http://ember-simple-auth.com/).
 *
 * @public
 * @class GroupControlAuthenticator
 * @extends EmberSimpleAuth.BaseAuthenticator
 * @module Miscellaneous
 */
export default Base.extend({

    /**
     * Injected Config service
     *
     * @private
     * @property config
     * @type ConfigService
     */
    config: injectService(),

    /**
     * Injected Current User service
     *
     * @private
     * @property currentUser
     * @type CurrentUserService
     */
    currentUser: injectService(),

    /**
     * Injected Ajax service
     *
     * @private
     * @property ajax
     * @type AjaxService
     */
    ajax: injectService(),

    /**
     * Injected Notifications service
     *
     * @private
     * @property notifications
     * @type NotificationsService
     */
    notifications: injectService(),

    /**
     * Overrides Ember-Simple-Auth's `restore` method.
     *
     * Restores user data on page reload. If the session has expired, automatically
     * logout the user.
     *
     * @public
     * @method restore
     * @return {Promise} Promise that resolves on successful restoration, otherwise rejects
     */
    restore() {
        let app = this.get('config.appId');
        let restoreUrl = this.get('config').formGCUrl('session');

        return this.get('ajax').request(restoreUrl, {data: {app}}, true).then((data) => {
            this.get('currentUser').setProperties(data);
            this.get('currentUser').trigger('login');
        });
    },

    /**
     * Authenticates a user given a username and password.
     *
     * @public
     * @method authenticate
     * @param  {String} user       Username to attempt login with
     * @param  {String} pass       User-provided password to attempt login with
     * @param  {String} department Query parameter preferred department
     * @return {Promise}     Promise that resolves upon successful login, otherwise rejects
     */
    authenticate(user, pass, department = undefined) {
        let app = this.get('config.appId');
        let data = JSON.stringify({
            user,
            pass,
            app,
            department
        });

        return this.get('ajax').post(this.get('config').formGCUrl('session'), {
            data,
            contentType: 'application/json'
        }, true).then((data) => {
            if (data.isSecure === false) {
                this.get('currentUser').changePassword(true);
            }

            this.get('currentUser').setProperties(data);
            this.get('currentUser').trigger('login');
        });
    },

    /**
     * Invalidates a user's session. Called on logout.
     *
     * @public
     * @method invalidate
     * @return {Promise}
     */
    invalidate() {
        return this.get('ajax').del(this.get('config').formGCUrl('session'), {}, true);
    }
});