// Copyright (c) 2022-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


//! Graph builder is the only class that has the ability to modify topology of a graph.
//!
//! Topological edits of the graph are only allowed during graph transformation and should never
//! be performed during execution of the graph. Construction of the builder will automatically drop
//! all the connections between nodes.
//!
//! Methods on this class mutating a graph topology are not thread-safe (unless documented otherwise)
template <>
class omni::core::Generated<omni::graph::exec::unstable::IGraphBuilder_abi>
    : public omni::graph::exec::unstable::IGraphBuilder_abi
{
public:
    OMNI_PLUGIN_INTERFACE("omni::graph::exec::unstable::IGraphBuilder")

    //! Return owner of all graphs this builder touches
    //!
    //! The returned @ref omni::graph::exec::unstable::IGraph will *not* have
    //! @ref omni::core::IObject::acquire() called before being returned.
    omni::graph::exec::unstable::IGraph* getGraph() noexcept;

    //! Returns the topology this builder can modify.
    //!
    //! The returned @ref omni::graph::exec::unstable::ITopology will *not* have
    //! @ref omni::core::IObject::acquire() called before being returned.
    omni::graph::exec::unstable::ITopology* getTopology() noexcept;

    //! Returns the context in which this builder works.
    //!
    //! The returned @ref omni::graph::exec::unstable::IGraphBuilderContext will *not* have
    //! @ref omni::core::IObject::acquire() called before being returned.
    omni::graph::exec::unstable::IGraphBuilderContext* getContext() noexcept;

    //! Returns @ref omni::graph::exec::unstable::INodeGraphDef this builder can modify.
    //!
    //! The returned @ref omni::graph::exec::unstable::INodeGraphDef will *not* have
    //! @ref omni::core::IObject::acquire() called before being returned.
    omni::graph::exec::unstable::INodeGraphDef* getNodeGraphDef() noexcept;

    //! Connect two given nodes.
    //!
    //! It is an error if the two nodes are not in the same topology.
    //!
    //! Neither given node should be @c nullptr.
    //!
    //! Neither @ref omni::graph::exec::unstable::INode have @ref omni::core::IObject::acquire() called
    //! during the connection process.
    //!
    //! May throw.
    void connect(omni::core::ObjectParam<omni::graph::exec::unstable::INode> upstreamNode,
                 omni::core::ObjectParam<omni::graph::exec::unstable::INode> downstreamNode);

    //! Disconnect two given nodes.
    //!
    //! It is an error if the two nodes are not in the same topology.
    //!
    //! Neither given node should be @c nullptr.
    //!
    //! Neither @ref omni::graph::exec::unstable::INode have @ref omni::core::IObject::acquire() called
    //! during the disconnection process.
    //!
    //! May throw.
    void disconnect(omni::core::ObjectParam<omni::graph::exec::unstable::INode> upstreamNode,
                    omni::core::ObjectParam<omni::graph::exec::unstable::INode> downstreamNode);

    //! Remove a node from topology.
    //!
    //! The given node must not be @c nullptr.
    //!
    //! May throw.
    void remove(omni::core::ObjectParam<omni::graph::exec::unstable::INode> node);

    //! Sets the definition for given node.
    //!
    //! If a definition is already set, it will be replaced by the given definition.
    //!
    //! The given definition may be @c nullptr.
    //!
    //! @ref omni::core::IObject::acquire() is called on the given definition pointer.
    //!
    //! See also  @ref omni::graph::exec::unstable::IGraphBuilder::setNodeGraphDef().
    //!
    //! This method is NOT thread safe.
    void setNodeDef(omni::core::ObjectParam<omni::graph::exec::unstable::INode> node,
                    omni::core::ObjectParam<omni::graph::exec::unstable::INodeDef> nodeDef) noexcept;

    //! Sets the definition for give node.
    //!
    //! If a definition is already set, it will be replaced by the given definition.
    //!
    //! The given definition may be @c nullptr.
    //!
    //! @ref omni::core::IObject::acquire() is called on the given definition pointer.
    //!
    //! See also  @ref omni::graph::exec::unstable::IGraphBuilder::setNodeDef().
    //!
    //! This method is NOT thread safe.
    void setNodeGraphDef(omni::core::ObjectParam<omni::graph::exec::unstable::INode> node,
                         omni::core::ObjectParam<omni::graph::exec::unstable::INodeGraphDef> nodeGraphDef) noexcept;

    //! Unsets given node's definition.
    //!
    //! If the definition is already @c nullptr, this method does nothing.
    //!
    //! This method is NOT thread safe.
    void clearDef(omni::core::ObjectParam<omni::graph::exec::unstable::INode> node) noexcept;

    //! Replace well formed cluster of nodes with a single node and the given definition.
    //!
    //! All nodes must exist in the same and current topology, otherwise the entire operation is aborted.
    //!
    //! @ref omni::core::IObject::acquire() is called on the given definition pointer.
    //!
    //! This method is NOT thread safe.
    void replacePartition(const omni::graph::exec::unstable::NodePartition& partition,
                          omni::core::ObjectParam<omni::graph::exec::unstable::IDef> definition);

    //! Create a new node in current node graph def.
    //!
    //! The given node name must not be @c nullptr.
    //!
    //! The given node def can be @c nullptr.
    //!
    //! Node creation can return @c nullptr when current node graph def doesn't allow node construction outside
    //! of the pass that created it.
    //!
    //! The returned @ref omni::graph::exec::unstable::INode will have @ref omni::core::IObject::acquire() called on it.
    omni::core::ObjectPtr<omni::graph::exec::unstable::INode> createNode(
        const char* name, omni::core::ObjectParam<omni::graph::exec::unstable::IDef> def);

    //! Access created nodes by this builder.
    //!
    //! Span is no longer valid when topology of the graph changes. You need to query it again.
    //!
    //! In case a node once created gets removed by another pass, returned list will continue to have it.
    //! It is safe to do, because we do not delete underlying nodes until the next graph population.
    //! Checking if node is valid in current topology allows to filter out these cases.
    //!
    //! The pointers in the span are non owning, i.e. @ref omni::graph::exec::unstable::INode will not have
    //! @ref omni::core::IObject::acquire() called on it.
    omni::graph::exec::unstable::Span<omni::graph::exec::unstable::INode* const> getCreatedNodes() noexcept;
};

#endif

#ifndef OMNI_BIND_INCLUDE_INTERFACE_DECL

inline omni::graph::exec::unstable::IGraph* omni::core::Generated<omni::graph::exec::unstable::IGraphBuilder_abi>::getGraph() noexcept
{
    return getGraph_abi();
}

inline omni::graph::exec::unstable::ITopology* omni::core::Generated<
    omni::graph::exec::unstable::IGraphBuilder_abi>::getTopology() noexcept
{
    return getTopology_abi();
}

inline omni::graph::exec::unstable::IGraphBuilderContext* omni::core::Generated<
    omni::graph::exec::unstable::IGraphBuilder_abi>::getContext() noexcept
{
    return getContext_abi();
}

inline omni::graph::exec::unstable::INodeGraphDef* omni::core::Generated<
    omni::graph::exec::unstable::IGraphBuilder_abi>::getNodeGraphDef() noexcept
{
    return getNodeGraphDef_abi();
}

inline void omni::core::Generated<omni::graph::exec::unstable::IGraphBuilder_abi>::connect(
    omni::core::ObjectParam<omni::graph::exec::unstable::INode> upstreamNode,
    omni::core::ObjectParam<omni::graph::exec::unstable::INode> downstreamNode)
{
    OMNI_THROW_IF_ARG_NULL(upstreamNode);
    OMNI_THROW_IF_ARG_NULL(downstreamNode);
    OMNI_THROW_IF_FAILED(connect_abi(upstreamNode.get(), downstreamNode.get()));
}

inline void omni::core::Generated<omni::graph::exec::unstable::IGraphBuilder_abi>::disconnect(
    omni::core::ObjectParam<omni::graph::exec::unstable::INode> upstreamNode,
    omni::core::ObjectParam<omni::graph::exec::unstable::INode> downstreamNode)
{
    OMNI_THROW_IF_ARG_NULL(upstreamNode);
    OMNI_THROW_IF_ARG_NULL(downstreamNode);
    OMNI_THROW_IF_FAILED(disconnect_abi(upstreamNode.get(), downstreamNode.get()));
}

inline void omni::core::Generated<omni::graph::exec::unstable::IGraphBuilder_abi>::remove(
    omni::core::ObjectParam<omni::graph::exec::unstable::INode> node)
{
    OMNI_THROW_IF_ARG_NULL(node);
    OMNI_THROW_IF_FAILED(remove_abi(node.get()));
}

inline void omni::core::Generated<omni::graph::exec::unstable::IGraphBuilder_abi>::setNodeDef(
    omni::core::ObjectParam<omni::graph::exec::unstable::INode> node,
    omni::core::ObjectParam<omni::graph::exec::unstable::INodeDef> nodeDef) noexcept
{
    setNodeDef_abi(node.get(), nodeDef.get());
}

inline void omni::core::Generated<omni::graph::exec::unstable::IGraphBuilder_abi>::setNodeGraphDef(
    omni::core::ObjectParam<omni::graph::exec::unstable::INode> node,
    omni::core::ObjectParam<omni::graph::exec::unstable::INodeGraphDef> nodeGraphDef) noexcept
{
    setNodeGraphDef_abi(node.get(), nodeGraphDef.get());
}

inline void omni::core::Generated<omni::graph::exec::unstable::IGraphBuilder_abi>::clearDef(
    omni::core::ObjectParam<omni::graph::exec::unstable::INode> node) noexcept
{
    clearDef_abi(node.get());
}

inline void omni::core::Generated<omni::graph::exec::unstable::IGraphBuilder_abi>::replacePartition(
    const omni::graph::exec::unstable::NodePartition& partition,
    omni::core::ObjectParam<omni::graph::exec::unstable::IDef> definition)
{
    OMNI_THROW_IF_ARG_NULL(definition);
    replacePartition_abi(&partition, definition.get());
}

inline omni::core::ObjectPtr<omni::graph::exec::unstable::INode> omni::core::Generated<
    omni::graph::exec::unstable::IGraphBuilder_abi>::createNode(const char* name,
                                                                omni::core::ObjectParam<omni::graph::exec::unstable::IDef> def)
{
    OMNI_THROW_IF_ARG_NULL(name);
    auto return_ = omni::core::steal(createNode_abi(name, def.get()));
    return return_;
}

inline omni::graph::exec::unstable::Span<omni::graph::exec::unstable::INode* const> omni::core::Generated<
    omni::graph::exec::unstable::IGraphBuilder_abi>::getCreatedNodes() noexcept
{
    return getCreatedNodes_abi();
}

#endif

#undef OMNI_BIND_INCLUDE_INTERFACE_DECL
#undef OMNI_BIND_INCLUDE_INTERFACE_IMPL
