"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var def = require("raml-definition-system");
var services = def;
var _ = require("underscore");
var fs = require("fs");
var path = require("path");
var messageRegistry = require("../../../../resources/errorMessages");
//TODO implement pragrammatic grammar at some point
/**
 *Generates grammar for Atom from definition system at this moment we will use context free grammar
 *
 */
function iteratePropeties(u) {
    var result = "";
    var pNames = {};
    u.types().forEach(function (x) {
        x.allProperties().forEach(function (p) {
            if (pNames[p.nameId()]) {
                if (_.indexOf(pNames[p.nameId()], p) == -1) {
                    pNames[p.nameId()].push(p);
                }
            }
            else {
                pNames[p.nameId()] = [p];
            }
        });
    });
    Object.keys(pNames).forEach(function (x) {
        var props = pNames[x];
        var kinds = _.uniq(props.map(function (x) { return x.getAdapter(services.RAMLPropertyService).getPropertyGrammarType(); }));
        if (kinds.length > 1) {
            throw new Error(messageRegistry.PROPERTIES_SHOULD_HAVE_SAME_GRAMMAR_KIND.message);
        }
        result += generateNodePropertyDefinition(props[0]);
    });
    return result;
}
function generateKeyTemplate(p) {
    if (p.enumOptions() && p.getAdapter(services.RAMLPropertyService).isKey()) {
        return p.enumOptions().join("|");
    }
    if (p.keyPrefix() != null) {
        return escape(p.keyPrefix()) + "([^:]+)"; //FIXME
    }
    //if (p.i)
    return p.nameId();
}
function escape(n) {
    return n.replace("/", "\\\\/");
}
function generateNodePropertyDefinition(p) {
    var propKind = p.getAdapter(services.RAMLPropertyService).getPropertyGrammarType();
    if (!propKind) {
        propKind = "constant.character.method.yaml";
    }
    var keyTemplate = generateKeyTemplate(p);
    var end = "\\\\z|\\\\n";
    var tab = "\\\\t";
    var lineEnd = "((?:(\\\\![\\\\w\\\\!]+)\\\\s+?)?|\\\\Z|(?#))";
    var tag = ", {\n            token: \"" + propKind + "\",\n            regex: \"^[ " + tab + "]*(" + keyTemplate + ")(:)" + lineEnd + "\"\n        }";
    return tag;
}
function composeGrammar(u) {
    var s = fs.readFileSync(path.resolve(__dirname, "aceGrammarTemplate.js")).toString();
    var ip = "$INSERTION_POINT";
    var startIndex = s.indexOf(ip);
    return s.substr(0, startIndex) + iteratePropeties(u) + s.substr(startIndex + ip.length);
}
exports.composeGrammar = composeGrammar;
//# sourceMappingURL=aceGrammarGen.js.map