// Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//
// --------- Warning: This is a build system generated file. ----------
//

//! @file
//!
//! @brief This file was generated by <i>omni.bind</i>.

#include <omni/core/Interface.h>
#include <omni/core/OmniAttr.h>
#include <omni/core/ResultError.h>

#include <functional>
#include <type_traits>
#include <utility>

#ifndef OMNI_BIND_INCLUDE_INTERFACE_IMPL


/**
 * @brief Interface that creates a forward on a request for a node type to a different node type
 *
 * There are a couple of different common use cases for needing a forward:
 * - Node type gets renamed
 * - Node type moves from one extension to another
 *
 * The node type forward specifies the unique node type name so if extension omni.my.extension has a node whose type
 * is specified as "MyNode" then the forward must be from "omni.my.extension.MyNode".
 *
 * The forwarding is version-based as well, where the version is a minimum number required for forwarding, the usual
 * node version update mechanism not withstanding. For example, if you set up a forward from "omni.nodes.MyNode" version
 * 2 to "omni.my_nodes.MyNode" version 3 then any larger version number is forwarded to the same location:
 * - omni.nodes.MyNode(2) -> omni.my_nodes.MyNode(3)
 * - omni.nodes.MyNode(3) -> omni.my_nodes.MyNode(3)
 * - omni.nodes.MyNode(4) -> omni.my_nodes.MyNode(3)
 *
 * The forwards can also have multiple versions forwarding to different locations, so if on top of the above forward
 * you also add a forward from "omni.nodes.MyNode" version 3 to "omni.new_nodes.MyNode" version 4 then these become
 * the example forward locations:
 * - omni.nodes.MyNode(2) -> omni.my_nodes.MyNode(3)
 * - omni.nodes.MyNode(3) -> omni.new_nodes.MyNode(4)
 * - omni.nodes.MyNode(4) -> omni.new_nodes.MyNode(4)
 *
 * Version numbers lower than the first forward are left as-is
 * - omni.nodes.MyNode(1) -> omni.nodes.MyNode(1)
 *
 * @note The usual mechanism of calling updateVersionNumber on a node is only applied after a forward so in the above
 *       cases requesting omni.nodes.MyNode(2) does not call updateVersionNumber(1,2) on your omni.nodes.MyNode
 *       implementation.
 *
 * Node type forwards are associative, so if A forwards to B and B forwards to C then when you request A you get C.
 * Adding a new forward from omni.my_nodes.MyNode(3) to omni.new_nodes.MyNode(2) above yields this forwarding:
 * - omni.nodes.MyNode(2) -> omni.my_nodes.MyNode(3) -> omni.new_nodes.MyNode(2)
 * - omni.nodes.MyNode(3) -> omni.new_nodes.MyNode(4)
 * - omni.nodes.MyNode(4) -> omni.new_nodes.MyNode(4)
 */
template <>
class omni::core::Generated<omni::graph::core::unstable::INodeTypeForwarding_abi>
    : public omni::graph::core::unstable::INodeTypeForwarding_abi
{
public:
    OMNI_PLUGIN_INTERFACE("omni::graph::core::unstable::INodeTypeForwarding")

    /**
     * @returns Number of currently defined forwards
     */
    size_t getForwardCount() noexcept;

    /**
     * @brief Get the list of available forwards and their redirections.
     * Note that there is no guarantee that the replacement names are legitimate node type names, only that they
     * have been registered as replacements.
     *
     * The caller is responsible for allocating and destroying buffers large enough to hold "bufferSize" results.
     * If bufferSize > getForwardCount() then the entries at the ends of the buffers will be filled with nullptr.
     *
     * @param[out] forwardNameBuffer List of forward names to be replaced
     * @param[out] forwardVersionBuffer List of the first version of each forward name to be replaced
     * @param[out] replacementNameBuffer List of node type names that replace the forwarded names
     * @param[out] replacementVersionBuffer List of node type versions that replace the forwarded names
     * @param[out] extensionIdBuffer List of extension IDs corresponding to the replacement node type names.
     * @param[in] bufferSize Number of entries to fill in the buffers
     * @return true if the buffers were successfully filled and the bufferSize matched the forward count
     */
    bool getForwards(const char** forwardNameBuffer,
                     int* forwardVersionBuffer,
                     const char** replacementNameBuffer,
                     int* replacementVersionBuffer,
                     const char** extensionIdBuffer,
                     size_t bufferSize) noexcept;

    /**
     * @brief Define a new node type forward.
     * It is allowed to have the same forwardName to be defined more than once, however the "forwardVersion" must be
     * different from any existing ones. Later "forwardVersion" numbers will supersede earlier ones in this case.
     * For example if you have these two forwards set up:
     *     OldNode,1 -> BetterNode,1,omni.better.extension
     *     OldNode,2 -> MuchBetterNode,1,omni.much_better.extension
     * then when version 1 of "OldNode" is requested it will treat it as if you requested "BetterNode", but when
     * versions 2 or later are requested it will instead treat it as if you requested "MuchBetterNode". These can be
     * chained together:
     *     OldNode,1 -> BetterNode,1,omni.better.extension
     *     BetterNode,1 -> MuchBetterNode,1,omni.much_better.extension
     *
     * @param[in] forwardName Name to be replaced
     * @param[in] forwardVersion The first version of the forward name to be replaced
     * @param[in] replacementName Node type name that replaces the forwarded name
     * @param[in] replacementVersion Version of the node type that replaces the forwarded name
     * @param[in] extensionId Extension ID in which the replacement node type can be found
     * @return false if there was already an forward with the given name and initial version number
     */
    bool defineForward(const char* forwardName,
                       int forwardVersion,
                       const char* replacementName,
                       int replacementVersion,
                       const char* replacementExtensionId) noexcept;

    /**
     * @brief Remove an existing node type forward.
     * Since an forwardName + forwardVersion combination is unique there is no need to pass in the replacement
     * information. Only the forward with the matching version is removed. Any others with the same name remain
     * untouched.
     *
     * @param[in] forwardName Forward to be removed
     * @param[in] forwardVersion The version at which the forward is to be removed
     * @return false if there was already an forward with the given name and initial version number
     */
    bool removeForward(const char* forwardName, int forwardVersion) noexcept;

    /**
     * @brief Remove forwards referencing a given node type name.
     *
     * @param[in] referencedName Forward to be removed
     * @param[in] referencedVersion The version at which the forward is to be removed
     * @return number of forwards to the given type that were removed
     */
    size_t removeForwardedType(const char* referencedName, int referencedVersion) noexcept;

    /**
     * @brief Find a node type name replacement corresponding to the given node type forward name and version
     *
     * @param[in] forwardName Name of the node type forward to look up
     * @param[in] forwardVersion Version number of the node type forward being looked up
     * @param[out] nodeTypeName Pointer to the name of the actual node type name corresponding to the forward,
     *                          or nullptr if there is no equivalent. This string is a constant and managed
     *                          by the node type forward system so it should not be stored on a long-term basis.
     * @param[out] nodeTypeVersion Pointer to the version of the actual node type name corresponding to the forward
     * @param[out] nodeTypeExtension Pointer to the name of the extension owning nodeTypeName
     * @return true if the forwardName/forwardVersion found a valid mapping, with the result placed in the return
     * parameters
     */
    bool findForward(const char* forwardName,
                     int forwardVersion,
                     const char** nodeTypeName,
                     int* nodeTypeVersion,
                     const char** nodeTypeExtension) noexcept;
};

#endif

#ifndef OMNI_BIND_INCLUDE_INTERFACE_DECL

inline size_t omni::core::Generated<omni::graph::core::unstable::INodeTypeForwarding_abi>::getForwardCount() noexcept
{
    return getForwardCount_abi();
}

inline bool omni::core::Generated<omni::graph::core::unstable::INodeTypeForwarding_abi>::getForwards(
    const char** forwardNameBuffer,
    int* forwardVersionBuffer,
    const char** replacementNameBuffer,
    int* replacementVersionBuffer,
    const char** extensionIdBuffer,
    size_t bufferSize) noexcept
{
    return getForwards_abi(forwardNameBuffer, forwardVersionBuffer, replacementNameBuffer, replacementVersionBuffer,
                           extensionIdBuffer, bufferSize);
}

inline bool omni::core::Generated<omni::graph::core::unstable::INodeTypeForwarding_abi>::defineForward(
    const char* forwardName,
    int forwardVersion,
    const char* replacementName,
    int replacementVersion,
    const char* replacementExtensionId) noexcept
{
    return defineForward_abi(forwardName, forwardVersion, replacementName, replacementVersion, replacementExtensionId);
}

inline bool omni::core::Generated<omni::graph::core::unstable::INodeTypeForwarding_abi>::removeForward(
    const char* forwardName, int forwardVersion) noexcept
{
    return removeForward_abi(forwardName, forwardVersion);
}

inline size_t omni::core::Generated<omni::graph::core::unstable::INodeTypeForwarding_abi>::removeForwardedType(
    const char* referencedName, int referencedVersion) noexcept
{
    return removeForwardedType_abi(referencedName, referencedVersion);
}

inline bool omni::core::Generated<omni::graph::core::unstable::INodeTypeForwarding_abi>::findForward(
    const char* forwardName,
    int forwardVersion,
    const char** nodeTypeName,
    int* nodeTypeVersion,
    const char** nodeTypeExtension) noexcept
{
    return findForward_abi(forwardName, forwardVersion, nodeTypeName, nodeTypeVersion, nodeTypeExtension);
}

#endif

#undef OMNI_BIND_INCLUDE_INTERFACE_DECL
#undef OMNI_BIND_INCLUDE_INTERFACE_IMPL
