import ConfigService from '@bennerinformatics/ember-fw/services/config';
import EmberError from '@ember/error';
import {inject} from '@ember/service';
import {isEmpty, isNone} from '@ember/utils';

/**
 * At its base, the config service is used to form the proper ajax url to be used with the
 * [Ajax Service](https://linformatics.bitbucket.io/docs/addons/client-api/ember-fw-gc/classes/AppMeta.html) to
 * make a direct network call. Ember FW GC's config service extends Ember FW's config service, which can be found
 * [here](https://linformatics.bitbucket.io/docs/addons/client-api/ember-fw/classes/ConfigService.html). The basic usage
 * of calling a network request within the app you are currently logged into is described there (with `formUrl`).
 * Ember FW GC only adds a couple of functions to allow more complicated forming of url (such as forming a url
 * for another app). See the couple added functions below.
 *
 * For a detailed example of how to implement the config (and ajax) service at the basic level, see our
 * [Conceptual Introduction - Advanced Topics](https://linformatics.bitbucket.io/docs/training/intro/advanced/#ajax-requests).
 *
 * @public
 * @class ConfigService
 * @extends @bennerinformatics/services/config
 * @module Services
 */
export default ConfigService.extend({
    appMeta: inject(),

    /**
     * Forms a request to group control, expected to be an app dependency of this app. Automatically handles being in group control.
     * Same arguments and usage as [formUrl](https://linformatics.bitbucket.io/docs/addons/client-api/ember-fw/classes/ConfigService.html#method_formUrl).
     *
     * @method formGCUrl
     * @return {string}     AJAX url for an Group Control Ajax request
     */
    formGCUrl() {
        if (this.get('appId') === 'gc') {
            return this.formUrl(...arguments);
        }

        return this.formUrl('gc', ...arguments);
    },

    /**
     * Same arguments and usage as [formUrl](https://linformatics.bitbucket.io/docs/addons/client-api/ember-fw/classes/ConfigService.html#method_formUrl),
     * except it sends to another app besides the current one.
     *
     * @method formAppUrl
     * @param  {string} app App to send request to. Should be loaded using AppMetaService.findMeta
     * @return {string}     AJAX url for an inter-app ajax request
     */
    formAppUrl(app) {
        let args = Array.prototype.slice.call(arguments, 1);
        // we cannot use a promise for this as we need to return a string, not a promise
        let appMeta = this.get('appMeta').peekMeta(app);
        if (isNone(appMeta)) {
            throw new EmberError(`Metadata for app ${app} not fetched`);
        }
        if (isEmpty(appMeta)) {
            throw new EmberError(`Missing metadata for app ${app}`);
        }
        return this._formUrl(appMeta.get('apiUrl'), args);
    },

    /**
     * Same arguments and usage as [formUrl](https://linformatics.bitbucket.io/docs/addons/client-api/ember-fw/classes/ConfigService.html#method_formUrl),
     * except instead of returning the URL, returns a promise that resolves to the URL.
     *
     * @method promiseAppUrl
     * @param  {string} app App to send request to
     * @return {Promise}    Promise that returns an AJAX url for an inter-app ajax request
     */
    promiseAppUrl(app) {
        let args = Array.prototype.slice.call(arguments, 1);
        // return a promise that resolves to the URL string
        return this.get('appMeta').findMeta(app).then((meta) => {
            if (isNone(meta)) {
                throw new EmberError(`Missing metadata for app ${app}, cannot make request`);
            }
            return this._formUrl(meta.get('apiUrl'), args);
        });
    }
});