/*
 * Copyright (c) 2019, 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.
 */
#ifndef NVMTRACE_H
#define NVMTRACE_H

#include "NvSIPLDeviceBlockTrace.hpp"
#include <cstdlib>
#include <iostream>
#include <cstdarg>
#include <cstring>

namespace nvsipl
{

#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)

//! Quick-log a message at debugging level
#define LOG_DEBUG(...) \
    CNvSIPLDeviceBlockTrace::GetTrace().Trace(LEVEL_DBG, __FUNCTION__, __FILENAME__, __LINE__, __VA_ARGS__)

//! Quick-log a message at info level
#define LOG_INFO(...) \
    CNvSIPLDeviceBlockTrace::GetTrace().Trace(LEVEL_INFO, __FUNCTION__, __FILENAME__, __LINE__, __VA_ARGS__)

//! Quick-log a message at warning level
#define LOG_WARN(...) \
    CNvSIPLDeviceBlockTrace::GetTrace().Trace(LEVEL_WARN, __FUNCTION__, __FILENAME__, __LINE__, __VA_ARGS__)

//! Quick-log a message at error level
#define LOG_ERR(...) \
    CNvSIPLDeviceBlockTrace::GetTrace().Trace(LEVEL_ERR, __FUNCTION__, __FILENAME__, __LINE__, __VA_ARGS__)

#define LEVEL_NONE INvSIPLDeviceBlockTrace::LevelNone

#define LEVEL_ERR INvSIPLDeviceBlockTrace::LevelError

#define LEVEL_WARN INvSIPLDeviceBlockTrace::LevelWarning

#define LEVEL_INFO INvSIPLDeviceBlockTrace::LevelInfo

#define LEVEL_DBG INvSIPLDeviceBlockTrace::LevelDebug

class CNvSIPLDeviceBlockTrace:
    public INvSIPLDeviceBlockTrace
{
public:
    static CNvSIPLDeviceBlockTrace& GetTrace();

    void Trace(TraceLevel eLevel,
               const char* func,
               const char* file,
               int line,
               const char *pformat,
               ...);

    void SetHook(TraceFuncPtr pfnTraceHook,
                 bool bCallDefaultRenderer) override;

    virtual void SetLevel(TraceLevel eLevel) override;

    virtual void DisableLineInfo(void) override;

    bool m_bDefaultRender = true;
    bool m_appendLineInfo = true;
    TraceFuncPtr m_pfnTraceHook = nullptr;
    static const std::uint32_t m_uMaxLength = 8192;
    static const std::uint32_t m_uMaxLineInfo = 128;
    char m_message[m_uMaxLength] {};
    TraceLevel m_level = LevelError;
};

} // namespace nvsipl

#endif // NVMTRACE_H

