import createRouter from './router';
import requester from './requester';

let pluginSchemasCache;
let resultsCache = {};

export default ({host, https, ignoreConsumers, cache}) => {
    const router = createRouter(host, https);

    return createApi({
        router,
        ignoreConsumers,
        getPaginatedJson: cache ? getPaginatedJsonCache : getPaginatedJson,
    });
}

function createApi({ router, getPaginatedJson, ignoreConsumers }) {
    return {
        router,
        fetchApis: () => getPaginatedJson(router({name: 'apis'})),
        fetchGlobalPlugins: () => getPaginatedJson(router({name: 'plugins'})),
        fetchPlugins: apiName => getPaginatedJson(router({name: 'api-plugins', params: {apiName}})),
        fetchConsumers: () => ignoreConsumers ? Promise.resolve([]) : getPaginatedJson(router({name: 'consumers'})),
        fetchConsumerCredentials: (username, plugin) => getPaginatedJson(router({name: 'consumer-credentials', params: {username, plugin}})),
        fetchConsumerAcls: (username) => getPaginatedJson(router({name: 'consumer-acls', params: {username}})),

        // this is very chatty call and doesn't change so its cached
        fetchPluginSchemas: () => {
            if (pluginSchemasCache) {
                return Promise.resolve(pluginSchemasCache);
            }

            return getPaginatedJson(router({name: 'plugins-enabled'}))
                .then(json => Promise.all(json.enabled_plugins.map(plugin => getPluginScheme(plugin, plugin => router({name: 'plugins-scheme', params: {plugin}})))))
                .then(all => pluginSchemasCache = new Map(all));
        },
        requestEndpoint: (endpoint, params) => {
            resultsCache = {};
            return requester.request(router(endpoint), prepareOptions(params));
        }
    };
}

function getPaginatedJsonCache(uri) {
    if (resultsCache.hasOwnProperty(uri)) {
        return resultsCache[uri];
    }

    let result = getPaginatedJson(uri);
    resultsCache[uri] = result;

    return result;
}

function getPluginScheme(plugin, schemaRoute) {
    return getPaginatedJson(schemaRoute(plugin))
        .then(({fields}) => [plugin, fields]);
}

function getPaginatedJson(uri) {
    return requester.get(uri)
    .then(r => r.json())
    .then(json => {
        if (!json.data) return json;
        if (!json.next) return json.data;

        return json.data.concat(getPaginatedJson(json.next));
    });
}

const prepareOptions = ({method, body}) => {
    if (body) {
        return {
            method: method,
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
              },
            body: JSON.stringify(body)
        };
    }

    return {
        method: method,
        headers: {
            'Accept': 'application/json',
        }
    };
}

@@ -1421,16 +1421,38 @@
 ise.all(
+getEnabledPluginNames(
 json.ena
@@ -1463,16 +1463,17 @@
 _plugins
+)
 .map(plu
@@ -1820,24 +1820,186 @@
 %7D%0A    %7D;%0A%7D%0A%0A
+function getEnabledPluginNames(enabledPlugins) %7B%0A  if (!Array.isArray(enabledPlugins)) %7B%0A    return Object.keys(enabledPlugins);%0A  %7D%0A%0A  return enabledPlugins;%0A%7D%0A%0A
 function get

Fix getting enabled plugins