/* Generated from Java with JSweet 2.3.7 - http://www.jsweet.org */
import { JsonCompat } from '../../compat/JsonCompat';
import { NodeCompat } from '../../compat/NodeCompat';
import { RegexCompat } from '../../compat/RegexCompat';
import { Constants } from '../Constants';
import { Node } from '../models/Node';
/**
 * @author eric.wittmann@gmail.com
 * @class
 */
var ReferenceUtil = /** @class */ (function () {
    function ReferenceUtil() {
    }
    ReferenceUtil.resolveNodeRef$io_apicurio_datamodels_core_models_Node = function (node) {
        return ReferenceUtil.resolveNodeRef$io_apicurio_datamodels_core_models_Node$io_apicurio_datamodels_core_util_ResolverOptions(node, ResolverOptions.of(ResolverOptionsType.RECURSIVE));
    };
    ReferenceUtil.resolveNodeRef$io_apicurio_datamodels_core_models_Node$io_apicurio_datamodels_core_util_ResolverOptions = function (node, options) {
        if (!ReferenceUtil.hasValue(node)) {
            return null;
        }
        var $ref = NodeCompat.getProperty(node, Constants.PROP_$REF);
        return ReferenceUtil.resolveRef$java_lang_String$io_apicurio_datamodels_core_models_Node$io_apicurio_datamodels_core_util_ResolverOptions($ref, node, options);
    };
    /**
     * Resolves a node reference.  If there is no "$ref" property on the node, then the node itself is
     * returned.  If there is a "$ref" property, then it is resolved (if possible) to another node.
     * @param {Node} node
     * @param {ResolverOptions} options
     * @return {Node}
     */
    ReferenceUtil.resolveNodeRef = function (node, options) {
        if (((node != null && node instanceof Node) || node === null) && ((options != null && options instanceof ResolverOptions) || options === null)) {
            return ReferenceUtil.resolveNodeRef$io_apicurio_datamodels_core_models_Node$io_apicurio_datamodels_core_util_ResolverOptions(node, options);
        }
        else if (((node != null && node instanceof Node) || node === null) && options === undefined) {
            return ReferenceUtil.resolveNodeRef$io_apicurio_datamodels_core_models_Node(node);
        }
        else
            throw new Error('invalid overload');
    };
    ReferenceUtil.resolveRef$java_lang_String$io_apicurio_datamodels_core_models_Node = function ($ref, from) {
        if (!ReferenceUtil.hasValue($ref)) {
            return null;
        }
        return ReferenceUtil.resolveRef$java_lang_String$io_apicurio_datamodels_core_models_Node$io_apicurio_datamodels_core_util_ResolverOptions($ref, from, ResolverOptions.of(ResolverOptionsType.RECURSIVE, ResolverOptionsType.NULL_IF_NOT_FOUND));
    };
    ReferenceUtil.resolveRef$java_lang_String$io_apicurio_datamodels_core_models_Node$io_apicurio_datamodels_core_util_ResolverOptions = function ($ref, from, options) {
        var resolver = ReferenceResolverChain.getInstance();
        var rval = null;
        if (ReferenceUtil.hasValue($ref)) {
            rval = resolver.resolveRef($ref, from);
        }
        if (rval != null && options.contains(ResolverOptionsType.RECURSIVE)) {
            var observedRefs = ([]);
            var done = false;
            while ((!done)) {
                {
                    /* add */ (function (s, e) { if (s.indexOf(e) == -1) {
                        s.push(e);
                        return true;
                    }
                    else {
                        return false;
                    } })(observedRefs, $ref);
                    $ref = NodeCompat.getProperty(rval, Constants.PROP_$REF);
                    if (ReferenceUtil.hasValue($ref) && !(observedRefs.indexOf(($ref)) >= 0)) {
                        rval = resolver.resolveRef($ref, from);
                    }
                    else if ( /* contains */(observedRefs.indexOf(($ref)) >= 0)) {
                        rval = null;
                        done = true;
                    }
                    else {
                        done = true;
                    }
                    if (!ReferenceUtil.hasValue(rval)) {
                        done = true;
                    }
                }
            }
            ;
        }
        if (rval != null) {
            return rval;
        }
        if (options.contains(ResolverOptionsType.NULL_IF_NOT_FOUND)) {
            return null;
        }
        else {
            return from;
        }
    };
    /**
     * Resolves a reference from a relative position in the data model.
     * @param $ref
     * @param {Node} from
     * @param {ResolverOptions} options
     * @param {string} $ref
     * @return {Node}
     */
    ReferenceUtil.resolveRef = function ($ref, from, options) {
        if (((typeof $ref === 'string') || $ref === null) && ((from != null && from instanceof Node) || from === null) && ((options != null && options instanceof ResolverOptions) || options === null)) {
            return ReferenceUtil.resolveRef$java_lang_String$io_apicurio_datamodels_core_models_Node$io_apicurio_datamodels_core_util_ResolverOptions($ref, from, options);
        }
        else if (((typeof $ref === 'string') || $ref === null) && ((from != null && from instanceof Node) || from === null) && options === undefined) {
            return ReferenceUtil.resolveRef$java_lang_String$io_apicurio_datamodels_core_models_Node($ref, from);
        }
        else
            throw new Error('invalid overload');
    };
    /**
     * Returns true only if the given reference can be resolved relative to the given document.  Examples
     * of $ref values include:
     *
     * #/definitions/ExampleDefinition
     * #/parameters/fooId
     * #/responses/NotFoundResponse
     *
     * @param $ref
     * @param {Node} from
     * @param {string} $ref
     * @return {boolean}
     */
    ReferenceUtil.canResolveRef = function ($ref, from) {
        return ReferenceUtil.hasValue(ReferenceUtil.resolveRef$java_lang_String$io_apicurio_datamodels_core_models_Node($ref, from));
    };
    /**
     * Check if the property value exists (is not undefined and is not null).
     * @param {*} value
     * @return {boolean}
     */
    ReferenceUtil.hasValue = function (value) {
        return !NodeCompat.isNullOrUndefined(value);
    };
    /**
     * Resolves the given $ref fragment (e.g. /components/schemas/MySchema) against the
     * given JS Object context.  This operates against raw javascript, not against a
     * data model.
     * @param {*} contextNode
     * @param {string} fragment
     * @return {*}
     */
    ReferenceUtil.resolveFragmentFromJS = function (contextNode, fragment) {
        var split = RegexCompat.findMatches(fragment, "([^/]+)/?");
        var cnode = contextNode;
        for (var index125 = 0; index125 < split.length; index125++) {
            var mi = split[index125];
            {
                var seg = mi[1];
                if (NodeCompat.equals(seg, "#")) {
                    cnode = contextNode;
                }
                else if (cnode != null) {
                    cnode = JsonCompat.getProperty(cnode, seg);
                }
            }
        }
        return cnode;
    };
    return ReferenceUtil;
}());
export { ReferenceUtil };
ReferenceUtil["__class"] = "io.apicurio.datamodels.core.util.ReferenceUtil";
import { ReferenceResolverChain } from './ReferenceResolverChain';
import { ResolverOptionsType } from './ResolverOptionsType';
import { ResolverOptions } from './ResolverOptions';
//# sourceMappingURL=ReferenceUtil.js.map