"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var def = require("./definitionSystem");
var khttp = require("know-your-http-well");
var _ = require("underscore");
var services = def;
function handleTypeAnnotation(a, rangeType) {
    if (a.name == 'MetaModel.declaresSubTypeOf') { //FIXME should be handled in same way as method annotations
        rangeType.getAdapter(services.RAMLService).setExtendedTypeName(a.arguments[0]);
    }
    if (a.name == 'MetaModel.nameAtRuntime') { //FIXME should be handled in same way as method annotations
        rangeType.setNameAtRuntime(a.arguments[0]);
    }
    if (a.name == 'MetaModel.description') { //FIXME should be handled in same way as method annotations
        rangeType.withDescription(a.arguments[0]);
    }
    if (a.name == 'MetaModel.inlinedTemplates') {
        rangeType.getAdapter(services.RAMLService).setInlinedTemplates(true);
    }
    if (a.name == 'MetaModel.requireValue') { //FIXME should be handled in same way as method annotations
        rangeType.getAdapter(services.RAMLService).withContextRequirement("" + a.arguments[0], "" + a.arguments[1]);
    }
    if (a.name == 'MetaModel.referenceIs') { //FIXME should be handled in same way as method annotations
        rangeType.getAdapter(services.RAMLService).withReferenceIs("" + a.arguments[0]);
    }
    //MetaModel.referenceIs
    if (a.name == 'MetaModel.actuallyExports') { //FIXME should be handled in same way as method annotations
        rangeType.getAdapter(services.RAMLService).withActuallyExports("" + a.arguments[0]);
    }
    if (a.name == 'MetaModel.convertsToGlobalOfType') { //FIXME should be handled in same way as method annotations
        rangeType.getAdapter(services.RAMLService).withConvertsToGlobal("" + a.arguments[0]);
    }
    if (a.name == 'MetaModel.allowAny') { //FIXME should be handled in same way as method annotations
        rangeType.getAdapter(services.RAMLService).withAllowAny();
    }
    if (a.name == 'MetaModel.allowQuestion') {
        rangeType.getAdapter(services.RAMLService).withAllowQuestion();
    }
    if (a.name == 'MetaModel.alias') { //FIXME should be handled in same way as method annotations
        rangeType.getAdapter(services.RAMLService).addAlias("" + a.arguments[0]);
    }
    if (a.name == 'MetaModel.consumesRefs') { //FIXME should be handled in same way as method annotations
        rangeType.getAdapter(services.RAMLService).setConsumesRefs(true);
    }
    if (a.name == 'MetaModel.canInherit') { //FIXME should be handled in same way as method annotations
        rangeType.getAdapter(services.RAMLService).withCanInherit("" + a.arguments[0]);
    }
    if (a.name == 'MetaModel.definingPropertyIsEnough') { //FIXME should be handled in same way as method annotations
        rangeType.getAdapter(services.RAMLService).definingPropertyIsEnough("" + a.arguments[0]);
    }
    if (a.name == 'MetaModel.customHandling') {
        rangeType.setCustom(true);
    }
    if (a.name == 'MetaModel.superclasses') {
        rangeType.getAdapter(services.RAMLService).registerSupertypes(a.arguments[0]);
    }
    if (a.name == 'MetaModel.possibleInterfaces') {
        rangeType.getAdapter(services.RAMLService).registerPossibleInterfaces(a.arguments[0]);
    }
}
exports.handleTypeAnnotation = handleTypeAnnotation;
exports.annotationHandlers = {
    key: function (a, f) {
        f.withFromParentKey();
        f.withKey(true);
    },
    value: function (a, f) {
        f.withFromParentValue();
    },
    canBeValue: function (a, f) {
        f.withCanBeValue();
    },
    unmerged: function (a, f) {
        f.unmerge();
    },
    startFrom: function (a, f) {
        f.withKeyRestriction(a.arguments[0]);
        f.merge();
    },
    oneOf: function (a, f) {
        f.withEnumOptions(a.arguments[0]);
    },
    oftenKeys: function (a, f) {
        f.withOftenKeys(a.arguments[0]);
    },
    embeddedInMaps: function (a, f) {
        f.getAdapter(services.RAMLPropertyParserService).withEmbedMap();
    },
    system: function (a, f) {
        f.getAdapter(services.RAMLPropertyParserService).withSystem(true);
    },
    required: function (a, f) {
        if (a.arguments[0] != 'false' && a.arguments[0] !== false) {
            f.withRequired(true);
        }
    },
    noDirectParse: function (a, f) {
        if (a.arguments[0] != 'false' && a.arguments[0] !== false) {
            f.withNoDirectParse();
        }
    },
    setsContextValue: function (a, f) {
        f.addChildValueConstraint(new def.ChildValueConstraint("" + a.arguments[0], "" + a.arguments[1]));
        //f.withKeyRestriction(<string>a.arguments[0])
    },
    defaultValue: function (a, f) {
        f.setDefaultVal("" + a.arguments[0]);
    },
    defaultIntegerValue: function (a, f) {
        f.setDefaultIntegerVal(a.arguments[0]);
    },
    defaultBooleanValue: function (a, f) {
        f.setDefaultBooleanVal(a.arguments[0]);
    },
    facetId: function (a, f) {
        if (a.arguments[0] == "minItems") {
            f.setFacetValidator(function (x, f) {
                if (x instanceof Array) {
                    var length = Number.parseInt("" + f.value());
                    if (length > x.length) {
                        return "array should contain at least " + f.value() + " items";
                    }
                }
                return null;
            });
        }
        if (a.arguments[0] == "enum") {
            f.setFacetValidator(function (x, f) {
                var validateAgainst = x + "";
                var array = f;
                try {
                    if (!array.some(function (x) { return x == validateAgainst; })) {
                        return "value should be one of :" + array.join(",");
                    }
                }
                catch (e) {
                    return;
                }
                return null;
            });
        }
        if (a.arguments[0] == "maxItems") {
            f.setFacetValidator(function (x, f) {
                if (x instanceof Array) {
                    var length = Number.parseInt("" + f);
                    if (length < x.length) {
                        return "array should contain not more then " + f.value() + " items";
                    }
                }
                return null;
            });
        }
        if (a.arguments[0] == "minProperties") {
            f.setFacetValidator(function (x, f) {
                if (x instanceof Object) {
                    var length = Number.parseInt("" + f);
                    if (length > Object.keys(x).length) {
                        return "object should contain at least " + f.value() + " properties";
                    }
                }
                return null;
            });
        }
        if (a.arguments[0] == "maxProperties") {
            f.setFacetValidator(function (x, f) {
                if (x instanceof Object) {
                    var length = Number.parseInt("" + f);
                    if (length < Object.keys(x).length) {
                        return "object should contain not more then " + f.value() + " properties";
                    }
                }
                return null;
            });
        }
        if (a.arguments[0] == "uniqueItems") {
            f.setFacetValidator(function (x, f) {
                if (f instanceof Array) {
                    var length = _.unique(f).length;
                    if (length < f.length) {
                        return "array should contain only unique items";
                    }
                }
                return null;
            });
        }
        if (a.arguments[0] == "minLength") {
            f.setFacetValidator(function (x, f) {
                if (typeof x == 'number' || typeof x == 'boolean') {
                    x = "" + x;
                }
                if (typeof x == 'string') {
                    var length = Number.parseInt("" + f);
                    if (length > x.length) {
                        return "string length should be at least " + length;
                    }
                }
                return null;
            });
        }
        if (a.arguments[0] == "maxLength") {
            f.setFacetValidator(function (x, f) {
                if (typeof x == 'number' || typeof x == 'boolean') {
                    x = "" + x;
                }
                if (typeof x == 'string') {
                    var length = Number.parseInt("" + f);
                    if (length < x.length) {
                        return "string length should be not more then " + length;
                    }
                }
                return null;
            });
        }
        if (a.arguments[0] == "minimum") {
            f.setFacetValidator(function (x, f) {
                if (typeof x == 'string') {
                    x = parseFloat(x);
                }
                if (typeof x == 'number') {
                    var length = parseFloat(f);
                    if (length > x) {
                        return "value should be not less then " + length;
                    }
                }
                return null;
            });
        }
        if (a.arguments[0] == "maximum") {
            f.setFacetValidator(function (x, f) {
                if (typeof x == 'string') {
                    x = parseFloat(x);
                }
                if (typeof x == 'number') {
                    var length = parseFloat(f);
                    if (length < x) {
                        return "value should be not more then " + length;
                    }
                }
                return null;
            });
        }
        if (a.arguments[0] == "pattern") {
            f.setFacetValidator(function (x, f) {
                if (typeof x == 'number' || typeof x == 'boolean') {
                    x = "" + x;
                }
                if (typeof x == 'string') {
                    var regExp = new RegExp(f);
                    if (!regExp.test(x)) {
                        return "string should match to " + f;
                    }
                }
                return null;
            });
        }
    },
    extraMetaKey: function (a, f) {
        if (a.arguments[0] == "statusCodes") {
            f.withOftenKeys(khttp.statusCodes.filter(function (statusCode) { return statusCode.code.indexOf("x") < 0; }).map(function (x) { return x.code; }));
            f.setValueDocProvider(function (name) {
                var s = _.find(khttp.statusCodes, function (x) { return x.code == name; });
                if (s) {
                    return (name + ":" + s.description);
                }
                return null;
            });
        }
        if (a.arguments[0] == "headers") {
            f.setValueSuggester(function (x) {
                if (x.property()) {
                    var c = x.property().getChildValueConstraints();
                    if (_.find(c, function (x) {
                        return x.name == "location" && x.value == "Params.ParameterLocation.HEADERS";
                    })) {
                        return khttp.headers.map(function (x) { return x.header; });
                    }
                    if (x.property()) {
                        if (x.property().nameId() == "headers") {
                            return khttp.headers.map(function (x) { return x.header; });
                        }
                    }
                }
                return null;
            });
            f.setValueDocProvider(function (name) {
                var s = _.find(khttp.headers, function (x) { return x.header == name; });
                if (s) {
                    return (name + ":" + s.description);
                }
                return null;
            });
        }
        if (a.arguments[0] == "methods") {
            f.setValueDocProvider(function (name) {
                var s = _.find(khttp.methods, function (x) { return x.method == name.toUpperCase(); });
                if (s) {
                    return (name + ":" + s.description);
                }
                return null;
            });
            //f.withEnumOptions(khttp.methods.map(x=>x.method.toLowerCase()))
        }
    },
    requireValue: function (a, f) {
        f.withContextRequirement("" + a.arguments[0], "" + a.arguments[1]);
        //f.withKeyRestriction(<string>a.arguments[0])
    },
    allowMultiple: function (a, f) {
        f.withMultiValue(true);
        //f.withKeyRestriction(<string>a.arguments[0])
    },
    constraint: function (a, f) {
        //f.withKeyRestriction(<string>a.arguments[0])
    },
    newInstanceName: function (a, f) {
        f.withNewInstanceName("" + a.arguments[0]);
        //f.withKeyRestriction(<string>a.arguments[0])
    },
    declaringFields: function (a, f) {
        f.withThisPropertyDeclaresFields();
        //f.withKeyRestriction(<string>a.arguments[0])
    },
    describesAnnotation: function (a, f) {
        //f.withReferenceParameters();
        f.withDescribes(a.arguments[0]);
    },
    allowNull: function (a, f) {
        f.withAllowNull();
    },
    descriminatingProperty: function (a, f) {
        //f.withReferenceParameters();
        f.withDescriminating(true);
    },
    description: function (a, f) {
        f.withDescription("" + a.arguments[0]);
        //f.withReferenceParameters();
        //f.withDescriminating(true)
    },
    inherited: function (a, f) {
        f.withInherited(true);
    },
    selfNode: function (a, f) {
        f.withSelfNode();
    },
    grammarTokenKind: function (a, f) {
        f.getAdapter(services.RAMLPropertyService).withPropertyGrammarType("" + a.arguments[0]);
    },
    canInherit: function (a, f) {
        f.withInheritedContextValue("" + a.arguments[0]);
    },
    canBeDuplicator: function (a, f) {
        f.setCanBeDuplicator();
    },
    example: function (a, f) {
        f.getAdapter(services.RAMLPropertyService).setExample(true);
    },
    typeExpression: function (a, f) {
        f.getAdapter(services.RAMLPropertyService).setTypeExpression(true);
    },
    hide: function (a, f) {
        if (a.arguments.length == 0) {
            f.getAdapter(services.RAMLPropertyDocumentationService).setHidden(true);
        }
        else {
            f.getAdapter(services.RAMLPropertyDocumentationService).setHidden(a.arguments[0]);
        }
    },
    documentationTableLabel: function (a, f) {
        f.getAdapter(services.RAMLPropertyDocumentationService).setDocTableName("" + a.arguments[0]);
    },
    markdownDescription: function (a, f) {
        f.getAdapter(services.RAMLPropertyDocumentationService).setMarkdownDescription("" + a.arguments[0]);
    },
    valueDescription: function (a, f) {
        f.getAdapter(services.RAMLPropertyDocumentationService).setValueDescription(a.arguments[0] != null ? ("" + a.arguments[0]) : null);
    },
    customHandling: function (a, f) {
    }
};
function recordAnnotation(p, a) {
    exports.annotationHandlers[a.name](a, p);
}
exports.recordAnnotation = recordAnnotation;
//# sourceMappingURL=annotationHandlers.js.map