"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  {\n    'begin': '^[ " + tab + "]*(" + keyTemplate + ")(:)" + lineEnd + "'\n    'beginCaptures':\n      '1':\n        'name': '" + propKind + "'\n      '2':\n        'name': 'punctuation.colon.key-value.yaml'\n      '3':\n        'name': 'support.type.tag.yaml'\n    'end': '$'\n    'name': 'meta.method'\n    'patterns': [\n      {\n        'begin': '#'\n        'beginCaptures':\n          '0':\n            'name': 'punctuation.definition.comment.yaml'\n        'end': '" + end + "'\n        'name': 'comment.line.number-sign.yaml'\n      }\n      {\n        'include': '#scalars'\n      }\n    ]\n  }\n";
    return tag;
}
function composeGrammar(u) {
    var s = fs.readFileSync(path.resolve(__dirname, "grammarTemplate.cson")).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=atomGrammarGen.js.map