/**
 * @file       driver_log.h
 * @brief      Platform-depended API to logging
 * @author     Ivan Vorobiov (i.vorobiov@samsung.com)
 * @version    1.0
 * @date       Created Jun 6, 2016
 * @copyright  In Samsung Ukraine R&D Center (SURC) under a contract between
 * @copyright  LLC "Samsung Electronics Ukraine Company" (Kiev, Ukraine) and
 * @copyright  "Samsung Electronics Co", Ltd (Seoul, Republic of Korea)
 * @copyright  Copyright: (c) Samsung Electronics Co, Ltd 2016. All rights reserved.
**/

#ifndef PA_TZ_DRV_SRC_DRIVER_LOG_H_
#define PA_TZ_DRV_SRC_DRIVER_LOG_H_

#include <tees_log.h>

#ifndef PRINT_KERNLOG
#define PROCA_LOG(level, ...) TEES_LOG(level, __VA_ARGS__)
#define PROCA_LOGMEM(level, ...) TEES_LOGMEM(level, __VA_ARGS__)
#else
void PrintLogToKernel(TEES_LogLevel level, const char *function_name, int line, 
                         const char *project_name, const char *fmt, ...);
void PrintMemToKernel(TEES_LogLevel level, const char *function_name, int line,
                    const char *project_name, const void *data,
                    uint32_t data_len);
#define PROCA_LOG(level, ...) \
  if (level >= TEES_LOG_LEVEL_WARNING) {\
    PrintLogToKernel(level, __FUNCTION__, __LINE__, PLATFORM_LOG_TAG, __VA_ARGS__); \
  } else { \
    TEES_LOG(level, __VA_ARGS__); \
  }
#define PROCA_LOGMEM(level, ...) \
  if (level >= TEES_LOG_LEVEL_WARNING) { \
    PrintMemToKernel(level, __FUNCTION__, __LINE__, PLATFORM_LOG_TAG, __VA_ARGS__); \
  } else { \
    TEES_LOGMEM(level, __VA_ARGS__); \
  }
#endif

#ifdef CONFIG_KERNEL_32
#define LOGADDR(level, msg, addr) PROCA_LOG(level, "%s0x%08x\n", msg, addr)
#else
#define LOGADDR(level, msg, addr) PROCA_LOG(level, "%s0x%08x%08x\n", msg, (uint32_t)((addr) >> 32), (uint32_t)addr)
#endif

/**
 * Only LOG_W and LOG_E are used in Release configuration.
 * These macros allow to pass only string messages due to security reason.
 * LOG_W should be used in case if PROCA can recover error.
 * Default print level is set to Info in entry.c (Debug and Verbose messages
 * are not printed in Debug configuration by default)
 */
#ifndef DEBUG_PA
#define LOG_V(...)
#define LOG_D(...)
#define LOG_I(msg)  PROCA_LOG(TEES_LOG_LEVEL_INFO, "%s", msg)
#define LOG_W(msg)  PROCA_LOG(TEES_LOG_LEVEL_WARNING, "%s", msg)
#define LOG_E(msg)  PROCA_LOG(TEES_LOG_LEVEL_ERROR, "%s", msg)

#define LOGM_V(...)
#define LOGM_I(...)
#define LOGM_D(...)
#define LOGM_E(...)  PROCA_LOGMEM(TEES_LOG_LEVEL_ERROR, __VA_ARGS__)

#define LOGADDR_V(...)
#define LOGADDR_I(...)
#define LOGADDR_D(...)
#define LOGADDR_E(...)
#else
#define LOG_V(...)  PROCA_LOG(TEES_LOG_LEVEL_VERBOSE, __VA_ARGS__)
#define LOG_D(...)  PROCA_LOG(TEES_LOG_LEVEL_DEBUG, __VA_ARGS__)
#define LOG_I(msg)  PROCA_LOG(TEES_LOG_LEVEL_INFO, "%s", msg)
#define LOG_W(msg)  PROCA_LOG(TEES_LOG_LEVEL_WARNING, "%s", msg)
#define LOG_E(msg)  PROCA_LOG(TEES_LOG_LEVEL_ERROR, "%s", msg)

#define LOGM_V(...)  PROCA_LOGMEM(TEES_LOG_LEVEL_VERBOSE, __VA_ARGS__)
#define LOGM_I(...)  PROCA_LOGMEM(TEES_LOG_LEVEL_INFO, __VA_ARGS__)
#define LOGM_D(...)  PROCA_LOGMEM(TEES_LOG_LEVEL_DEBUG, __VA_ARGS__)

#define LOGADDR_V(msg, addr) LOGADDR(TEES_LOG_LEVEL_VERBOSE, msg, addr)
#define LOGADDR_I(msg, addr) LOGADDR(TEES_LOG_LEVEL_INFO, msg, addr)
#define LOGADDR_D(msg, addr) LOGADDR(TEES_LOG_LEVEL_DEBUG, msg, addr)
#define LOGADDR_E(msg, addr) LOGADDR(TEES_LOG_LEVEL_ERROR, msg, addr)
#endif

#endif  // PA_TZ_DRV_SRC_DRIVER_LOG_H_
