// 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 Assert.h
//!
//! @brief Defines macros for assertions.
#pragma once

#include <carb/extras/Debugging.h>

#include <omni/core/Assert.h>
#include <omni/core/ResultError.h>
#include <omni/graph/exec/unstable/IBase.h>

//! Debug build assertion.
#define OMNI_GRAPH_EXEC_ASSERT(cond, ...) OMNI_ASSERT(cond, ##__VA_ARGS__)

#ifndef DOXYGEN_BUILD
#    define OMNI_GRAPH_EXEC_BREAK_ON_ERROR
#endif

#if defined(OMNI_GRAPH_EXEC_BREAK_ON_ERROR) || defined(DOXYGEN_BUILD)
//! Returns the given @ref omni::core::Result.  If a debugger is attached, it will break.
#    define OMNI_GRAPH_EXEC_RETURN_ERROR(e_)                                                                           \
        carb::extras::debuggerBreak();                                                                                 \
        return e_;
#else
#    define OMNI_GRAPH_EXEC_RETURN_ERROR(e_) return e_;
#endif

//! When authoring ABI methods, use this macro to convert exceptions to @ref omni::core::Result codes.
#define OMNI_GRAPH_EXEC_CATCH_ABI_EXCEPTION()                                                                          \
    catch (const omni::core::ResultError& e_)                                                                          \
    {                                                                                                                  \
        OMNI_GRAPH_EXEC_RETURN_ERROR(e_.getResult());                                                                  \
    }                                                                                                                  \
    catch (...)                                                                                                        \
    {                                                                                                                  \
        OMNI_GRAPH_EXEC_RETURN_ERROR(omni::core::kResultFail);                                                         \
    }

//! Casts @p obj_ to an object of type @p type_.  If the cast fails, an exception is thrown.
//!
//! The resulting pointer is stored in @p var_.
#define OMNI_GRAPH_EXEC_CAST_OR_RETURN(var_, type_, obj_)                                                              \
    auto var_ = omni::graph::exec::unstable::cast<type_>(obj_);                                                        \
    do                                                                                                                 \
    {                                                                                                                  \
        if (!var_)                                                                                                     \
        {                                                                                                              \
            OMNI_GRAPH_EXEC_RETURN_ERROR(omni::core::kResultNoInterface);                                              \
        }                                                                                                              \
    } while (0)
