"use strict";
var path = require("path");
var introspection_1 = require("./introspection");
/**
 * Plugin Base implementation
 */
var Plugin = (function () {
    function Plugin(document, projectPackage, graphdocPackage) {
        var _this = this;
        this.document = document;
        this.projectPackage = projectPackage;
        this.graphdocPackage = graphdocPackage;
        this.queryType = null;
        this.mutationType = null;
        this.subscriptionType = null;
        this.typeMap = {};
        this.directiveMap = {};
        this.document.types = this.document.types ?
            this.document.types.sort(sortTypes) : [];
        this.document.directives = this.document.directives ?
            this.document.directives.sort(function (a, b) { return a.name.localeCompare(b.name); }) : [];
        this.document.types.forEach(function (type) {
            _this.typeMap[type.name] = type;
        });
        this.document.directives.forEach(function (directive) {
            _this.directiveMap[directive.name] = directive;
        });
        if (document.queryType) {
            this.queryType = this.typeMap[document.queryType.name];
        }
        if (document.mutationType) {
            this.mutationType = this.typeMap[document.mutationType.name];
        }
        if (document.subscriptionType) {
            this.subscriptionType = this.typeMap[document.subscriptionType.name];
        }
    }
    Plugin.collect = function (collection) {
        var result = [];
        collection
            .forEach(function (item) {
            if (Array.isArray(item))
                result = result.concat(item);
        });
        return result;
    };
    Plugin.collectNavigations = function (plugins, buildForType) {
        return Promise
            .all(plugins.map(function (plugin) {
            return plugin.getNavigations ?
                plugin.getNavigations(buildForType) :
                null;
        }))
            .then(function (navigationCollection) { return Plugin.collect(navigationCollection); });
    };
    Plugin.collectDocuments = function (plugins, buildForType) {
        return Promise
            .all(plugins.map(function (plugin) {
            return plugin.getDocuments ?
                plugin.getDocuments(buildForType) :
                null;
        }))
            .then(function (navigationCollection) { return Plugin.collect(navigationCollection); });
    };
    Plugin.collectHeaders = function (plugins, buildForType) {
        return Promise
            .all(plugins.map(function (plugin) {
            return plugin.getHeaders ?
                plugin.getHeaders(buildForType) :
                null;
        }))
            .then(function (assetCollection) { return Plugin.collect(assetCollection); });
    };
    Plugin.collectAssets = function (plugins) {
        return Promise
            .all(plugins.map(function (plugin) {
            return plugin.getAssets ?
                plugin.getAssets() :
                null;
        }))
            .then(function (assetCollection) { return Plugin.collect(assetCollection); });
    };
    Plugin.prototype.url = function (type) {
        return path.resolve(this.projectPackage.graphdoc.baseUrl, introspection_1.getFilenameOf(type));
    };
    return Plugin;
}());
exports.Plugin = Plugin;
var NavigationSection = (function () {
    function NavigationSection(title, items) {
        if (items === void 0) { items = []; }
        this.title = title;
        this.items = items;
    }
    return NavigationSection;
}());
exports.NavigationSection = NavigationSection;
var NavigationItem = (function () {
    function NavigationItem(text, href, isActive) {
        this.text = text;
        this.href = href;
        this.isActive = isActive;
    }
    return NavigationItem;
}());
exports.NavigationItem = NavigationItem;
function priorityType(type) {
    return (0 /* initial priority */ |
        (type.name[0] === '_' ? 1 : 0) /* protected type priority */ |
        (type.name[0] === '_' && type.name[1] === '_' ? 2 : 0) /* spec type priority */);
}
function sortTypes(a, b) {
    var priorityA = priorityType(a);
    var priorityB = priorityType(b);
    if (priorityA === priorityB) {
        return a.name.localeCompare(b.name);
    }
    else {
        return priorityA - priorityB;
    }
}
exports.sortTypes = sortTypes;
