/******************************************************************************

  Copyright (C), 2011-2017 PeitaoShi @LRVS, All Rights Reserved.

  THIS SOFTWARE IS PROTECTED UNDER SOURCE CODE AGREEMENT OR NON-DISCLOSURE AGREEMENT. 

  PERMISSION IS GRANTED TO LICENSE TO USE THIS SOFTWARE FOR ANY PURPOSE, INCLUDING
  COMMERICLA APPLICATION AND TO ALTER IT BUT NOT REDISTRIBUTE IT UNDER SORCE CODE 
  AGREEMENT/NON-DISCLOSUE AGREEMENT. YOU CAN NOT CLAIM THAT YOU WROTE THE SOFTWARE
  AFTER ALTERING SOURCE CODE.

  THIS SOFTWARE IS PROVIDED 'AS-IS', WITHOUT ANY EXPRESS OR IMPLIED WARRANTY.
  IN NO EVENT WILL THE AUTHOR(S) BE HELD LIABLE FOR NAY DAMGES ARISING FROM THE
  THE USER OF THIS SOFTWARE.

  ABOVE NOTICE SHOULD BE KEPT IN THE SOURCE CODE.

 ******************************************************************************
  File Name     : log_api.h

  Version       : 1.0

  Author        : Peitao Shi

  Description   : Embedded Logging is a solution targeted to limited embedded 
                platform even system log is not available. The logging information(
                warning, error and debug) messages can be logged in one or mulitple locations. 
                All log configurations are intialially loaded from configuration files ,and 
                can be overriden later by enviroment variable at running time. 

                If you want to log messages via the system syslog, you not only need set 
                syslog_enable =1, you also should ensure that your syslogd daemon is running.
                If you want to redirect redirectsyslog message to a specific file,you need to 
                locate and edit the syslog.conf file on your system.

                To the syslog daemon is not available or you don't want to use syslog,setting
                different destinations can rediret message to different locations , such as 
                writing local files or send to remote serer syslog server etc. The Embedded 
                logging supports remote trace with UDP packages. The messages are also displayed
                 with different colors locally or remotely.

                The new log settings can be run-time changed without doing reinitialization.
                by adding or updating same enviroment variables followed with "USR1" or "USR2"
                signals, the user can enable/disale logging, change debug level or destintions 
                etc. 

                In addition, Embeddd logging  provides simple logging rotations by cheching 
                logging files and number of files, which is especially suitable for flash based 
                embedded system. 

                 A log configuration file that defines all logging behavior has to be created 
                and loaded when logging moudle is initialized. See the following template.

                 For detail information on how to use API in log_api.h,please refer to 
                 Embedded logging user menual.

******************************************************************************/



#ifndef _LOG_API_H_
#define _LOG_API_H_

#include <sys/types.h>
#include <stdarg.h>
#include <limits.h>

#ifndef _STDIO_INCLUDED
#include <stdio.h>
#endif

#ifndef __ucosii__
  #error This Unimation Server requires
  #error the MicroC/OS-II Intellectual Property Software Component.
#endif
/* MicroC/OS-II definitions */
#include "includes.h"

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif

#define MAXLINELEN 4096


/**
 * @brief Basic Logging application levels with strictly defined IDs
 * @note In most cases, use LogAPP*_Error() ...LogAPP*_Debug() macros
 * @see severity levels in syslog.h
 */
typedef enum
{
    LOGAPP_FATAL = 0,
    LOGAPP_ERROR = 1, //error
    LOGAPP_WARN = 2,  // warning
    LOGAPP_INFO = 3,   // info
    LOGAPP_DEBUG = 4,   // debug
    LOGAPP_TOT_LEVEL=5
} LogAPP_Levels;


typedef enum
{  
    LOGFMT_LOCALTIME = 0,
    LOGFMT_RUNTIME = 1
} LOGFILE_FORMAT;

typedef struct
{
    int  log_level;
    int  log_format;
} s_config;



#define DbgPrintf(level,params...)    {\
                        LogApi_Output( 0, __FILE__, __LINE__, level, ##params );\
                }
/* avoid directly use*/
#define DbgHexdump(level,title,data,size)    {\
                        LogApi_Output( 1, __FILE__, __LINE__, level, "(%s %p %d)", title,data, size );\
                }

/* Turn off debug here */
#ifndef UNIMATION_DBG_OFF
#define Debug(level,params...)    DbgPrintf(level,##params)
#define Hexdump(level,data,len)    DbgHexdump(level,data,len)
#else
#define Debug(level,params...)
#define Hexdump(level,data,len)
#endif

/* system level logging interface */
#define LogSys_Info(params...)          DbgPrintf(SYS_LOG_INF,##params)
#define LogSys_Warning(params...)       DbgPrintf(SYS_LOG_WAR,##params)
#define LogSys_Error(params...)         DbgPrintf(SYS_LOG_ERR,##params)
#define LogSys_Fatal(params...)         DbgPrintf(SYS_LOG_FAT,##params)
#define LogSys_Panic(params...)         DbgPrintf(SYS_LOG_PNC,##params)
#define LogSys_Mark()                   SYSLOG_Info("Mark/%s/%d",__FILE__,__LINE__)
#define LogSys_Log()                    SYSLOG_Info("Log")

/* Application level logging interface */
#define LogApp_Emerg(params...)         DbgPrintf(LOGAPP_EMERG,##params)
#define LogApp_Alert(params...)         DbgPrintf(LOGAPP_ALERT,##params)
#define LogApp_Crit(params...)          DbgPrintf(LOGAPP_CRIT,##params)
#define LogApp_Error(params...)         DbgPrintf(LOGAPP_ERROR,##params)
#define LogApp_Warn(params...)          DbgPrintf(LOGAPP_WARN,##params)
#define LogApp_Notice(params...)        DbgPrintf(LOGAPP_NOTICE,##params)
#define LogApp_Info(params...)          DbgPrintf(LOGAPP_INFO,##params)
#define LogApp_Debug(params...)         DbgPrintf(LOGAPP_DEBUG,##params)


/*Application Hex dump */
#define LogApp_HexDump_Emerg(title,data,size)        DbgHexdump(LOGAPP_EMERG,title,data,size)
#define LogApp_HexDump_Alert(title,data,size)        DbgHexdump(LOGAPP_ALERT,title,data,size)
#define LogApp_HexDump_Crit(title,data,size)          DbgHexdump(LOGAPP_CRIT,title,data,size)
#define LogApp_HexDump_Error(title,data,size)        DbgHexdump(LOGAPP_ERROR,title,data,size)
#define LogApp_HexDump_Warn(title,data,size)         DbgHexdump(LOGAPP_WARN,title,data,size)
#define LogApp_HexDump_Notice(title,data,size)       DbgHexdump(LOGAPP_NOTICE,title,data,size)
#define LogApp_HexDump_Info(title,data,size)         DbgHexdump(LOGAPP_INFO,title,data,size)
#define LogApp_HexDump_Debug(title,data,size)        DbgHexdump(LOGAPP_DEBUG,title,data,size)

#ifdef __GNUC__
#define Enter(level)            DbgPrintf(level,("Entering %s",__PRETTY_FUNCTION__))
#define Exit(level)             DbgPrintf(level,("Exiting %s",__PRETTY_FUNCTION__))
#else
#if 0
#define Enter(level)            DbgPrintf(level,("Entering <unknown>"))
#define Exit(level)             DbgPrintf(level,("Exiting <unknown>"))
#endif
#define Enter(level)        
#define Exit(level)            
#endif


/* PRINT_COLOR     : 35(PURPLE) 34(BLUE) 33(YELLOW) 32(GREEN) 31(RED) */
#define ANSI_COLOR_RED     "\033[0;31m"
#define ANSI_COLOR_GREEN   "\033[0;32m"
#define ANSI_COLOR_YELLOW  "\033[0;33m"
#define ANSI_COLOR_BLUE    "\033[0;34m"
#define ANSI_COLOR_MAGENTA "\033[0;35m"
#define ANSI_COLOR_CYAN    "\033[0;36m"
#define ANSI_COLOR_RESET   "\033[0m"

#define PRINT_RED(s...)        printf(ANSI_COLOR_RED,##s,ANSI_COLOR_RESET)
#define PRINT_GREEN(s...)      printf(ANSI_COLOR_GREEN,##s,ANSI_COLOR_RESET);
#define PRINT_YELLOW(s...)     printf(ANSI_COLOR_YELLOW,##s,ANSI_COLOR_RESET);
#define PRINT_BLUE(s...)       printf(ANSI_COLOR_BLUE,##s,ANSI_COLOR_RESET);
#define PRINT_MAGENTA(s...)    printf(ANSI_COLOR_MAGENTA,##s,ANSI_COLOR_RESET);
#define PRINT_CYAN(s...)       printf(ANSI_COLOR_CYAN,##S,ANSI_COLOR_RESET);

#define ERROR_COLOR "\033[31m"
#define WARNING_COLOR "\033[33m"
#define OMIT_COLOR "\033[31m"
#define RESET_COLOR "\033[39;49;0m"

#ifdef __cplusplus
extern "C" {
#endif 

/* error color "\033[31m":thread safe;*/
void printf_error(const char *fmt, ...);
/* WARNING_COLOR "\033[33m" thread safe */
void printf_warn(const char *fmt, ...);
/* normal color: has output when log_level == LOGAPP_DEBUG only */
void printf_debug(const char *fmt, ...);


#if defined(__STDC__) || defined(__cplusplus)

/* function declarations */
void LogApi_Output( int hex, const char * const file, const int line,
        const int level, const char *fstring, ... ) 
        __attribute__ ((format(printf, 5, 6)));
#else

void LogApi_Output();
#endif


/*
 * Handle to our MicroC/OS-II LED Lightshow Semaphore. The semaphore is checked 
 * by the SSSLEDLightshowTask each time it updates 7 segment LED displays, 
 * U8 and U9.  The LEDTask grabs the semaphore away from the lightshow task to
 * toggle the lightshow off, and gives up the semaphore to turn the lightshow
 * back on.  The LEDTask does this in response to the CMD_LEDS_LIGHTSHOW
 * command sent from the SSSSimpleSocketServerTask when user sends the toggle 
 * lightshow command over the TCPIP socket.
 */
extern OS_EVENT *UniDebugSem;


#ifdef __cplusplus
} /* extern "C" */
#endif



#endif /* end of _LOG_API_H_ */


