#ifndef __MLOGGER_H__
#define __MLOGGER_H__
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
/* output log's level */
#define MLOG_LVL_ASSERT                      0
#define MLOG_LVL_ERROR                       1
#define MLOG_LVL_WARN                        2
#define MLOG_LVL_INFO                        3
#define MLOG_LVL_DEBUG                       4
#define MLOG_LVL_VERBOSE                     5

#define MLOG_LINE_SIZE  512
#define MLOG_BUFF_SIZE  (MLOG_LINE_SIZE*64)

typedef struct clog
{
    char  buff[MLOG_BUFF_SIZE];
    int r_idx;
    int w_idx;
    int bytes;
    
    sem_t sempare;
    pthread_mutex_t mutex;
    pthread_t threadID;

    char log_pathname[256];
    char log_basename[256];
    FILE *fp;

    int log_filesize; // bytes current file
    int max_filesize; // bytes pre file
    int max_filenumb; // files from running

    time_t  utc;
    struct tm ltm;

    int quit;

    char** flist;
    time_t *flutc;
    int fnumb;
}mlog_t;

void mlog_control(int level, int on);

int mlog_print(int level, const char *tag, const char* FUNCNAME, const char* FILENAME, int LINENO, const char *format, ...);

void mlog_init(const char* log_filename, int max_filesize, int max_filenumb);

void mlog_exit(void);

#define mlog_a(LOG_TAG, ...)       mlog_print(MLOG_LVL_ASSERT,  LOG_TAG, __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__)
#define mlog_e(LOG_TAG, ...)       mlog_print(MLOG_LVL_ERROR,   LOG_TAG, __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__)
#define mlog_w(LOG_TAG, ...)       mlog_print(MLOG_LVL_WARN,    LOG_TAG, __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__)
#define mlog_i(LOG_TAG, ...)       mlog_print(MLOG_LVL_INFO,    LOG_TAG, __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__)
#define mlog_d(LOG_TAG, ...)       mlog_print(MLOG_LVL_DEBUG,   LOG_TAG, __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__)
#define mlog_v(LOG_TAG, ...)       mlog_print(MLOG_LVL_VERBOSE, LOG_TAG, __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__)

#define printa(...)  mlog_print(MLOG_LVL_ASSERT,  NULL, __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__)
#define printe(...)  mlog_print(MLOG_LVL_ERROR,   NULL, __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__)
#define printw(...)  mlog_print(MLOG_LVL_WARN,    NULL, __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__)
#define printi(...)  mlog_print(MLOG_LVL_INFO,    NULL, __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__)
#define printd(...)  mlog_print(MLOG_LVL_DEBUG,   NULL, __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__)
#define printv(...)  mlog_print(MLOG_LVL_VERBOSE, NULL, __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__)

// #define printa(fmt,...)  printf("%s:%d, %s | "fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
// #define printe(fmt,...)  printf("%s:%d, %s | "fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
// #define printw(fmt,...)  printf("%s:%d, %s | "fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
// #define printi(fmt,...)  printf("%s:%d, %s | "fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
// #define printd(fmt,...)  printf("%s:%d, %s | "fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
// #define printv(fmt,...)  printf("%s:%d, %s | "fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)

#endif//__MLOGGER_H__
