/* Generated from Java with JSweet 2.3.7 - http://www.jsweet.org */
import { JsonCompat } from '../../compat/JsonCompat';
import { Constants } from '../Constants';
import { Node } from '../models/Node';
/**
 * Constructor.
 * @class
 * @author eric.wittmann@gmail.com
 */
var DataModelWriter = /** @class */ (function () {
    function DataModelWriter() {
        if (this._result === undefined)
            this._result = null;
        if (this._modelIdToJS === undefined)
            this._modelIdToJS = null;
        this.reset();
    }
    /**
     * Resets the visitor.
     * @private
     */
    /*private*/ DataModelWriter.prototype.reset = function () {
        this._modelIdToJS = ({});
    };
    /**
     * Gets the result of the writing.
     * @return {*}
     */
    DataModelWriter.prototype.getResult = function () {
        return JsonCompat.removeNullProperties(this._result);
    };
    DataModelWriter.prototype.updateIndex = function (node, json) {
        /* put */ (function (m, k, v) { if (m.entries == null)
            m.entries = []; for (var i = 0; i < m.entries.length; i++)
            if (m.entries[i].key.equals != null && m.entries[i].key.equals(k) || m.entries[i].key === k) {
                m.entries[i].value = v;
                return;
            } m.entries.push({ key: k, value: v, getKey: function () { return this.key; }, getValue: function () { return this.value; } }); })(this._modelIdToJS, node.modelId(), json);
        if (this._result == null) {
            this._result = json;
        }
    };
    DataModelWriter.prototype.writeExtraProperties = function (json, node) {
        node.getExtraPropertyNames().forEach(function (pname) {
            var value = node.getExtraProperty(pname);
            JsonCompat.setProperty(json, pname, value);
        });
    };
    /**
     * Lookup the parent node via modelId if it exists (we already processed it).
     * Caller must provide the parent object as a second argument for cases when it does not exist.
     * @param {number} modelId
     * @param {*} jsonDefault not null
     * @return {*}
     */
    DataModelWriter.prototype.lookup = function (modelId, jsonDefault) {
        /* requireNonNull */ if (jsonDefault == null) {
            throw new Error('cannot be null');
        }
        ;
        var rval = (function (m, k) { if (m.entries == null)
            m.entries = []; for (var i = 0; i < m.entries.length; i++)
            if (m.entries[i].key.equals != null && m.entries[i].key.equals(k) || m.entries[i].key === k) {
                return m.entries[i].value;
            } return null; })(this._modelIdToJS, modelId);
        if (rval == null) {
            rval = jsonDefault;
        }
        return rval;
    };
    DataModelWriter.prototype.lookupParentJson$io_apicurio_datamodels_core_models_Node = function (node) {
        return this.lookup(node.parent().modelId(), JsonCompat.objectNode());
    };
    DataModelWriter.prototype.lookupParentJson$io_apicurio_datamodels_core_models_Node$java_lang_Object = function (node, jsonDefault) {
        return this.lookup(node.parent().modelId(), jsonDefault);
    };
    DataModelWriter.prototype.lookupParentJson = function (node, jsonDefault) {
        if (((node != null && node instanceof Node) || node === null) && ((jsonDefault != null) || jsonDefault === null)) {
            return this.lookupParentJson$io_apicurio_datamodels_core_models_Node$java_lang_Object(node, jsonDefault);
        }
        else if (((node != null && node instanceof Node) || node === null) && jsonDefault === undefined) {
            return this.lookupParentJson$io_apicurio_datamodels_core_models_Node(node);
        }
        else
            throw new Error('invalid overload');
    };
    /**
     * @see io.apicurio.datamodels.core.visitors.IVisitor#visitDocument(io.apicurio.datamodels.core.models.Document)
     * @param {Document} node
     */
    DataModelWriter.prototype.visitDocument = function (node) {
        var root = JsonCompat.objectNode();
        this.writeDocument(node, root);
        this.updateIndex(node, root);
    };
    /**
     * Writes the document node info into the given json object.
     * @param {Document} node
     * @param {*} json
     */
    DataModelWriter.prototype.writeDocument = function (node, json) {
    };
    /**
     * @see io.apicurio.datamodels.core.visitors.IVisitor#visitExtension(io.apicurio.datamodels.core.models.Extension)
     * @param {Extension} node
     */
    DataModelWriter.prototype.visitExtension = function (node) {
        var parent = this.lookupParentJson$io_apicurio_datamodels_core_models_Node(node);
        JsonCompat.setProperty(parent, node.name, node.value);
    };
    /**
     * @see io.apicurio.datamodels.core.visitors.IVisitor#visitInfo(io.apicurio.datamodels.core.models.common.Info)
     * @param {Info} node
     */
    DataModelWriter.prototype.visitInfo = function (node) {
        var parent = this.lookupParentJson$io_apicurio_datamodels_core_models_Node(node);
        var json = JsonCompat.objectNode();
        JsonCompat.setPropertyString(json, Constants.PROP_TITLE, node.title);
        JsonCompat.setPropertyString(json, Constants.PROP_VERSION, node.version);
        JsonCompat.setPropertyString(json, Constants.PROP_DESCRIPTION, node.description);
        JsonCompat.setPropertyString(json, Constants.PROP_TERMS_OF_SERVICE, node.termsOfService);
        JsonCompat.setPropertyNull(json, Constants.PROP_CONTACT);
        JsonCompat.setPropertyNull(json, Constants.PROP_LICENSE);
        this.writeExtraProperties(json, node);
        JsonCompat.setProperty(parent, Constants.PROP_INFO, json);
        this.updateIndex(node, json);
    };
    /**
     * @see io.apicurio.datamodels.core.visitors.IVisitor#visitContact(io.apicurio.datamodels.core.models.common.Contact)
     * @param {Contact} node
     */
    DataModelWriter.prototype.visitContact = function (node) {
        var parent = this.lookupParentJson$io_apicurio_datamodels_core_models_Node(node);
        var json = JsonCompat.objectNode();
        JsonCompat.setPropertyString(json, Constants.PROP_NAME, node.name);
        JsonCompat.setPropertyString(json, Constants.PROP_URL, node.url);
        JsonCompat.setPropertyString(json, Constants.PROP_EMAIL, node.email);
        this.writeExtraProperties(json, node);
        JsonCompat.setProperty(parent, Constants.PROP_CONTACT, json);
        this.updateIndex(node, json);
    };
    /**
     * @see io.apicurio.datamodels.core.visitors.IVisitor#visitLicense(io.apicurio.datamodels.core.models.common.License)
     * @param {License} node
     */
    DataModelWriter.prototype.visitLicense = function (node) {
        var parent = this.lookupParentJson$io_apicurio_datamodels_core_models_Node(node);
        var json = JsonCompat.objectNode();
        JsonCompat.setPropertyString(json, Constants.PROP_NAME, node.name);
        JsonCompat.setPropertyString(json, Constants.PROP_URL, node.url);
        this.writeExtraProperties(json, node);
        JsonCompat.setProperty(parent, Constants.PROP_LICENSE, json);
        this.updateIndex(node, json);
    };
    /**
     * @see io.apicurio.datamodels.core.visitors.IVisitor#visitTag(io.apicurio.datamodels.core.models.common.Tag)
     * @param {Tag} node
     */
    DataModelWriter.prototype.visitTag = function (node) {
        var parent = this.lookupParentJson$io_apicurio_datamodels_core_models_Node(node);
        var json = JsonCompat.objectNode();
        JsonCompat.setPropertyString(json, Constants.PROP_NAME, node.name);
        JsonCompat.setPropertyString(json, Constants.PROP_DESCRIPTION, node.description);
        JsonCompat.setPropertyNull(json, Constants.PROP_EXTERNAL_DOCS);
        this.writeExtraProperties(json, node);
        JsonCompat.appendToArrayProperty(parent, Constants.PROP_TAGS, json);
        this.updateIndex(node, json);
    };
    /**
     * @see io.apicurio.datamodels.core.visitors.IVisitor#visitSecurityRequirement(io.apicurio.datamodels.core.models.common.SecurityRequirement)
     * @param {SecurityRequirement} node
     */
    DataModelWriter.prototype.visitSecurityRequirement = function (node) {
        var parent = this.lookupParentJson$io_apicurio_datamodels_core_models_Node(node);
        var json = JsonCompat.objectNode();
        node.getSecurityRequirementNames().forEach((function (json) {
            return function (name) {
                var scopes = node.getScopes(name);
                JsonCompat.setPropertyStringArray(json, name, scopes);
            };
        })(json));
        JsonCompat.appendToArrayProperty(parent, Constants.PROP_SECURITY, json);
        this.updateIndex(node, json);
    };
    /**
     * @see io.apicurio.datamodels.core.visitors.IVisitor#visitExternalDocumentation(io.apicurio.datamodels.core.models.common.ExternalDocumentation)
     * @param {ExternalDocumentation} node
     */
    DataModelWriter.prototype.visitExternalDocumentation = function (node) {
        var parent = this.lookupParentJson$io_apicurio_datamodels_core_models_Node(node);
        var json = JsonCompat.objectNode();
        JsonCompat.setPropertyString(json, Constants.PROP_DESCRIPTION, node.description);
        JsonCompat.setPropertyString(json, Constants.PROP_URL, node.url);
        this.writeExtraProperties(json, node);
        JsonCompat.setProperty(parent, Constants.PROP_EXTERNAL_DOCS, json);
        this.updateIndex(node, json);
    };
    /**
     * @see io.apicurio.datamodels.core.visitors.IVisitor#visitOperation(io.apicurio.datamodels.core.models.common.Operation)
     * @param {Operation} node
     */
    DataModelWriter.prototype.visitOperation = function (node) {
        var parent = this.lookupParentJson$io_apicurio_datamodels_core_models_Node(node);
        var json = JsonCompat.objectNode();
        this.writeOperation(json, node);
        this.writeExtraProperties(json, node);
        JsonCompat.setProperty(parent, node.getType(), json);
        this.updateIndex(node, json);
    };
    DataModelWriter.prototype.writeOperation = function (json, node) {
        JsonCompat.setPropertyString(json, Constants.PROP_OPERATION_ID, node.operationId);
        JsonCompat.setPropertyString(json, Constants.PROP_SUMMARY, node.summary);
        JsonCompat.setPropertyString(json, Constants.PROP_DESCRIPTION, node.description);
        JsonCompat.setPropertyNull(json, Constants.PROP_EXTERNAL_DOCS);
    };
    /**
     * @see io.apicurio.datamodels.core.visitors.IVisitor#visitParameter(io.apicurio.datamodels.core.models.common.Parameter)
     * @param {Parameter} node
     */
    DataModelWriter.prototype.visitParameter = function (node) {
        var parent = this.lookupParentJson$io_apicurio_datamodels_core_models_Node(node);
        var json = JsonCompat.objectNode();
        this.writeParameter(json, node);
        this.writeExtraProperties(json, node);
        JsonCompat.appendToArrayProperty(parent, Constants.PROP_PARAMETERS, json);
        this.updateIndex(node, json);
    };
    DataModelWriter.prototype.writeParameter = function (json, node) {
        JsonCompat.setPropertyString(json, Constants.PROP_$REF, node.$ref);
        JsonCompat.setPropertyString(json, Constants.PROP_NAME, node.name);
        JsonCompat.setPropertyString(json, Constants.PROP_DESCRIPTION, node.description);
        JsonCompat.setPropertyNull(json, Constants.PROP_SCHEMA);
    };
    /**
     * @see io.apicurio.datamodels.core.visitors.IVisitor#visitSchema(io.apicurio.datamodels.core.models.common.Schema)
     * @param {Schema} node
     */
    DataModelWriter.prototype.visitSchema = function (node) {
        this.doVisitSchema(node, Constants.PROP_SCHEMA, false);
    };
    DataModelWriter.prototype.doVisitSchema = function (node, parentPropertyName, isCollection) {
        var parent = this.lookupParentJson$io_apicurio_datamodels_core_models_Node(node);
        var json = JsonCompat.objectNode();
        this.writeSchema(json, node);
        this.writeExtraProperties(json, node);
        if (isCollection) {
            JsonCompat.appendToArrayProperty(parent, parentPropertyName, json);
        }
        else {
            JsonCompat.setProperty(parent, parentPropertyName, json);
        }
        this.updateIndex(node, json);
    };
    DataModelWriter.prototype.writeSchema = function (json, node) {
        JsonCompat.setPropertyString(json, Constants.PROP_$REF, node.$ref);
    };
    /**
     * @see io.apicurio.datamodels.core.visitors.IVisitor#visitValidationProblem(io.apicurio.datamodels.core.models.ValidationProblem)
     * @param {ValidationProblem} problem
     */
    DataModelWriter.prototype.visitValidationProblem = function (problem) {
    };
    /**
     * @see io.apicurio.datamodels.core.visitors.IVisitor#visitSecurityScheme(io.apicurio.datamodels.core.models.common.SecurityScheme)
     * @param {SecurityScheme} node
     */
    DataModelWriter.prototype.visitSecurityScheme = function (node) {
        var parent = this.lookupParentJson$io_apicurio_datamodels_core_models_Node(node);
        var json = JsonCompat.objectNode();
        this.writeSecurityScheme(json, node);
        this.writeExtraProperties(json, node);
        this.addSecuritySchemeToParent(parent, json, node);
        this.updateIndex(node, json);
    };
    DataModelWriter.prototype.writeSecurityScheme = function (json, node) {
        JsonCompat.setPropertyString(json, Constants.PROP_TYPE, node.type);
        JsonCompat.setPropertyString(json, Constants.PROP_DESCRIPTION, node.description);
        JsonCompat.setPropertyString(json, Constants.PROP_NAME, node.name);
        JsonCompat.setPropertyString(json, Constants.PROP_IN, node.in);
    };
    DataModelWriter.prototype.addSecuritySchemeToParent = function (parent, json, node) {
        JsonCompat.setProperty(parent, node.getSchemeName(), json);
    };
    /**
     * @see io.apicurio.datamodels.core.visitors.IVisitor#visitSchemaDefinition(io.apicurio.datamodels.core.models.common.IDefinition)
     * @param {*} node
     */
    DataModelWriter.prototype.visitSchemaDefinition = function (node) {
        var schema = node;
        var parent = this.lookupParentJson$io_apicurio_datamodels_core_models_Node(schema);
        var json = JsonCompat.objectNode();
        this.writeSchema(json, schema);
        this.writeExtraProperties(json, schema);
        this.addSchemaDefinitionToParent(parent, json, node);
        this.updateIndex(schema, json);
    };
    DataModelWriter.prototype.addSchemaDefinitionToParent = function (parent, json, node) {
        JsonCompat.setProperty(parent, node.getName(), json);
    };
    /**
     * @see io.apicurio.datamodels.core.visitors.IVisitor#visitParameterDefinition(io.apicurio.datamodels.core.models.common.IDefinition)
     * @param {*} node
     */
    DataModelWriter.prototype.visitParameterDefinition = function (node) {
        var pdef = node;
        var parent = this.lookupParentJson$io_apicurio_datamodels_core_models_Node(pdef);
        var json = JsonCompat.objectNode();
        this.writeParameter(json, pdef);
        this.writeExtraProperties(json, pdef);
        this.addParameterDefinitionToParent(parent, json, node);
        this.updateIndex(pdef, json);
    };
    DataModelWriter.prototype.addParameterDefinitionToParent = function (parent, json, node) {
        JsonCompat.setProperty(parent, node.getName(), json);
    };
    return DataModelWriter;
}());
export { DataModelWriter };
DataModelWriter["__class"] = "io.apicurio.datamodels.core.io.DataModelWriter";
DataModelWriter["__interfaces"] = ["io.apicurio.datamodels.core.visitors.IVisitor"];
//# sourceMappingURL=DataModelWriter.js.map