// 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.
//

//! @file NodeDef.h
//!
//! @brief Declares @ref omni::graph::exec::unstable::INodeDef.
#pragma once

#include <omni/graph/exec/unstable/Assert.h>
#include <omni/graph/exec/unstable/INodeDef.h>

namespace omni
{
namespace graph
{
namespace exec
{
namespace unstable
{

//! @copydoc omni::graph::exec::unstable::INodeDef
template <typename... Bases>
class NodeDefT : public Implements<Bases...>
{
public:
    //! Construct node definition
    //!
    //! @param  definitionName  Definition name is considered as a token that transformation passes can register against
    //!
    //! *TODO* Replace runtime hashing of node definition name to id with a compile time hash generation.
    //!
    //! May throw.
    static omni::core::ObjectPtr<NodeDefT> create(const char* definitionName)
    {
        OMNI_THROW_IF_ARG_NULL(definitionName);
        return omni::core::steal(new NodeDefT(definitionName));
    }

protected:
    //! Core implementation of @ref omni::graph::exec::unstable::IDef::execute_abi for @ref NodeDef
    //!
    //! Returns success without executing anything
    Status execute_abi(ExecutionTask* info) noexcept override
    {
        return Status::eSuccess;
    }

    //! Core implementation of @ref omni::graph::exec::unstable::IDef::getSchedulingInfo_abi for @ref NodeDef
    //!
    //! Returns serial scheduling
    SchedulingInfo getSchedulingInfo_abi(const ExecutionTask* info) noexcept override
    {
        return SchedulingInfo::eSerial;
    }

    //! Core implementation of @ref omni::graph::exec::unstable::IDef::getName_abi for @ref NodeDef
    const ConstName* getName_abi() noexcept override
    {
        return &m_name;
    }

    //! Constructor
    NodeDefT(const char* definitionName) : m_name{ definitionName }
    {
    }

private:
    ConstName m_name; //!< We associate a name with each opaque definition. This is where we store it.
};

//! Core NodeDef implementation for @ref omni::graph::exec::unstable::INodeDef
using NodeDef = NodeDefT<INodeDef>;

} // namespace unstable
} // namespace exec
} // namespace graph
} // namespace omni
