/* $Id$ 
 * 
 * Licensed to the Apache Software Foundation (ASF) under one or more 
 * contributor license agreements. See the NOTICE file distributed with  
 * this work for additional information regarding copyright ownership. 
 * The ASF licenses this file to you under the Apache License, Version  
 * 2.0 (the "License"); you may not use this file except in compliance  
 * with the License. You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */ 

/*
 * etchlog.c
 * etch c binding logger
 */

#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <time.h> 
#include <direct.h>
#include <sys/stat.h>

#if IS_WINDOWS_ETCH
#pragma warning(disable:4996) /* potentially unsafe function warning */
#endif

#include "etchthread.h"  /* for mutex */
#include "etchlog.h"
#include "etchutl.h"

void etchlog_timestamp (char*    buf, const char*    component, etchlog_level lvl);  
void etchlogw_timestamp(wchar_t* buf, const wchar_t* component, etchlog_level lvl);  
int  etchlog_copy_logfile(const int); 
#define ETCHLOG_STACKBUFSIZE 256
#define ETCHLOG_PREAMBLESIZE 19
#define ETCHLOG_STAMPLEN 12
#define ETCHLOG_CBUFLEN  4
char*   ETCHLOGX = "LOGX";

char* etchlog_level_str[] = 
{
    "X","D","I","W","E"
};

wchar_t* etchlogw_level_str[] = 
{
    L"X",L"D",L"I",L"W",L"E"
};

char  etchlogbuf[ETCHLOG_STACKBUFSIZE];
int   etch_loglines, etch_logfiles;
int   is_etch_logfile_open, is_etchlog_shutdown, is_etchlog_suspended;
FILE* flog;
char* logpath;
#define ETCHCLIENTLOGDIR  "../logcli"
#define ETCHCLIENTLOGPATH "../logcli/etchclient.log"
#define ETCHSERVERLOGDIR  "../logsrv" 
#define ETCHSERVERLOGPATH "../logsrv/etchserver.log"
#define IS_ETCH_LOG_FILE    TRUE
#define IS_ETCH_LOG_CONSOLE TRUE


/**
 * etchlog_open()
 * log file open.
 */
int etchlog_open (const int is_client)
{
    return is_client? etchlog_open_client(): etchlog_open_server();
}


/**
 * etchlog_open_server()
 * log file open.
 */
int etchlog_open_server()
{
    config.calculated_is_client = FALSE;
    return etchlog_openx(ETCHSERVERLOGPATH);
}


/**
 * etchlog_open_client()
 * client log file lazy open.
 */
int etchlog_open_client()
{
    config.calculated_is_client = TRUE;
    return etchlog_openx(ETCHCLIENTLOGPATH);  
}


/**
 * etchlog_openx()
 * log file lazy open.
 * note that the etch .exe directory will be different when the etch is started
 * in the debugger, than when it is started from the command line, and so the log
 * directories, being relative to the .exe directory, will change accordingly.
 */
int etchlog_openx (char* filepath)
{
    int result = 0;

    if (is_etch_logfile_open);
    else
    if (is_etchlog_shutdown)  
        result = -1;
    else  
    {   const char* dirpath = config.calculated_is_client? ETCHCLIENTLOGDIR: ETCHSERVERLOGDIR;
        mkdir (dirpath); /* create the log directory if it does not already exist */
        logpath = filepath; 

        #if(0) /* code to identify effective directory */
        { const char* t = "it works!", *fn = "etchtest.txt";  
          FILE* f = fopen(fn,"w"); size_t n = fwrite(t,1,strlen(t),f); fclose(f);
          printf("*** etchlog_openx wrote %d to %s\n", n, fn);  
        }
        #endif

        etchlog_copy_logfile (FALSE); /* back up etchlog.log */

        if (flog = fopen(filepath, "w")) 
        {   is_etch_logfile_open = TRUE;
            etch_loglines = 0;
        }
        else 
        {   printf("could not open log file %s\n", filepath);
            is_etchlog_shutdown = TRUE;
            result = -1;
        }
    }

    return result;
}


/**
 * etchlog_close()
 * currently can't be reopened.
 */
int etchlog_close()
{
    if (is_etch_logfile_open); 
        fclose(flog);
    is_etch_logfile_open = FALSE;
    is_etchlog_shutdown  = TRUE;
    return 0;
}
 

/**
 * etchlog_write()
 * write specified ansi string to log.
 * @return count of bytes written.
 */
int etchlog_write(char* buf)
{
    int bytecount = 0, bytesout = 0, result = 0;
    if (is_etchlog_suspended) return 0;

    if (buf && (0 > (bytecount = (int) strlen(buf)))) 
        if (config.is_log_to_file && is_etch_logfile_open && !is_etchlog_suspended)
            if (0 < (bytesout = (int) fwrite(buf, 1, bytecount, flog)))
            {   fflush(flog);  /* linecount assumes each line has a line feed */
                if (++etch_loglines >= config.max_log_lines)  
                {   result = etchlog_copy_logfile(TRUE);   /* copy and reopen */
                    assert(0 == result);
                }
            }

    return bytesout;
}


/**
 * etchlog()
 * write ansi string to log.
 */
void etchlog (char *comp, etchlog_level level, const char *fmt, ...)
{
    char *buf;
    va_list args;
    int result = 0, arglen, totallen, charcount;

    if (level < config.loglevel) return;

    loglock->acquire(loglock); /* todo use a queue instead of serializing? */

    do {

    va_start(args, fmt);
    if (0 > (arglen = _vscprintf (fmt, args) + 1)) break;
   
    if ((totallen = arglen + ETCHLOG_PREAMBLESIZE) > ETCHLOG_STACKBUFSIZE)
         buf = malloc(totallen);  /* eschew etch_malloc since immediately freed */
    else buf = etchlogbuf;
    charcount = totallen - 1;  
    memset(buf,' ', charcount); buf[charcount] = '\0'; 

    if (strlen(comp) > 4) comp[4] = '\0';     /* module id exactly 4 characters */

    etchlog_timestamp(buf, comp, level);

    vsprintf(buf + ETCHLOG_PREAMBLESIZE, fmt, args);
    va_end(fmt);

    #if IS_ETCH_LOG_CONSOLE      /* log to console, unless configured otherwise */
    if (config.is_log_to_console)
        printf(buf);  
    #endif /* IS_ETCH_LOG_CONSOLE */

    #if IS_ETCH_LOG_FILE            /* log to file, unless configured otherwise */
    if (config.is_log_to_file && is_etch_logfile_open && !is_etchlog_suspended)
        if (fwrite(buf, 1, charcount, flog) > 0)
        {   fflush(flog);    /* linecount assumes each line has a line feed */
            if (++etch_loglines >= config.max_log_lines) 
            {   result = etchlog_copy_logfile(TRUE);     /* copy and reopen */
                if (-1 == result) printf("*** LOGFILE COPY FAILED\n");
                assert(0 == result);
            }
        }
    #endif /* IS_ETCH_LOG_FILE */ 

    if (totallen > ETCHLOG_STACKBUFSIZE)
        free(buf);   /* see etch_malloc comment above */

    } while(0);

    loglock->release(loglock); /* todo use a queue instead of serializing */
}


/**
 * etchlogw()
 * write unicode string to log.
 */
void etchlogw (wchar_t *comp, etchlog_level level, const wchar_t *fmt, ...)
{
    wchar_t *buf;
    va_list args;
    int argcharlen, totalcharlen, bytelen;

    if (level < config.loglevel) return;

    loglock->acquire(loglock); /* todo use a queue instead of serializing? */

    do {

    va_start(args, fmt);
    if (0 > (argcharlen = _vscwprintf(fmt, args) + 1)) break;

    totalcharlen = argcharlen + ETCHLOG_PREAMBLESIZE;
    bytelen = totalcharlen * sizeof(wchar_t);
   
    if  (bytelen > ETCHLOG_STACKBUFSIZE)
         buf  = malloc(bytelen); /* eschew etch_malloc since immediately freed */
    else buf  = (wchar_t*) etchlogbuf;

    memset (buf, 0, bytelen);  
    wmemset(buf, L' ', totalcharlen);      

    if (wcslen(comp) > 4) comp[4] = L'\0';   /* module id exactly 4 characters */

    etchlogw_timestamp(buf, comp, level);

    /* note that offsets are specified in characters not bytes */
    vswprintf(buf + ETCHLOG_PREAMBLESIZE, totalcharlen, fmt, args);
    va_end((void*) fmt);
     

    #if IS_ETCH_LOG_CONSOLE     /* log to console, unless configured otherwise */
    if (config.is_log_to_console)
        wprintf(buf); 
    #endif /* IS_ETCH_LOG_CONSOLE */


    #if IS_ETCH_LOG_FILE        /* log to file, unless configured otherwise */
    if (config.is_log_to_file)
        if (0 == etchlog_open_server())
            if (fwrite(buf, 1, bytelen, flog) > 0)
            {   fflush(flog);
                if (++etch_loglines >= config.max_log_lines) 
                {   const int result = etchlog_copy_logfile(TRUE);  
                    assert(0 == result);
                }
            }
    #endif /* IS_ETCH_LOG_FILE */

    if (bytelen > ETCHLOG_STACKBUFSIZE)
        free(buf);   /* see etch_malloc comment above */

    } while(0);

    loglock->release(loglock); /* todo use a queue instead of serializing */
}


/** 
 * etchlog_timestamp()
 * sets preamble to supplied buffer which must be at least 20 bytes. 
 * string length of preamble is always 19.
 */
void etchlog_timestamp(char* buf, const char* component, etchlog_level lvl)   
{   /* 012345678901234567 */
    /* MMDD HHMMSS CCCC L */
    static const char* TIMESTAMPMASK = "%02d%02d %02d%02d%02d "; 
    char cbuf[ETCHLOG_CBUFLEN+1];
    struct tm* t;
    time_t l; 

    time(&l);                                
    t = localtime(&l);
    memset (cbuf,' ',ETCHLOG_CBUFLEN+1);
    memcpy (cbuf, component, strlen(component));

    sprintf(buf, TIMESTAMPMASK, /* t->tm_year+1900, */
            t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);

    memcpy(buf+12, cbuf, ETCHLOG_CBUFLEN);
    *(buf+17) = *etchlog_level_str[lvl];
    *(buf+19) = '\0'; /* caller will overwrite term */
}


/** 
 * etchlogw_timestamp()
 */
void etchlogw_timestamp(wchar_t* buf, const wchar_t* component, etchlog_level lvl)   
{   /* 012345678901234567 */
    /* MMDD HHMMSS CCCC L */
    static const wchar_t* TIMESTAMPMASKW = L"%02d%02d %02d%02d%02d "; 
    wchar_t cbuf[ETCHLOG_CBUFLEN+1];
    struct tm* t;
    time_t l; 

    time(&l);                                
    t = localtime(&l);
    wmemset (cbuf, L' ', ETCHLOG_CBUFLEN+1);
    wmemcpy (cbuf, component, wcslen(component));

    swprintf(buf, ETCHLOG_STAMPLEN+1, TIMESTAMPMASKW, /* t->tm_year+1900, */
            t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);

    wmemcpy(buf+12, cbuf, ETCHLOG_CBUFLEN);  /* note that numeric constants */
    *(buf+17) = *etchlog_level_str[lvl];    /* specify characters not bytes */
    *(buf+19) = '\0';  /* caller will overwrite term */
}


/**
 * etchlog_get_dirpath()
 * get the relative path to the log file directory.
 * @return a path string or null.
 */
char* etchlog_get_dirpath() 
{
    return config.calculated_is_client? ETCHCLIENTLOGDIR: ETCHSERVERLOGDIR;
}


/**
 * etchlog_get_logfile_count()
 * @return the current running count of log files.
 */
int etchlog_get_logfile_count() 
{                
    return etch_logfiles;
}


/**
 * etchlog_set_logfile_count()
 * set the initial count of log files.
 */
void etchlog_set_logfile_count(const int count) 
{                
    etch_logfiles = count;
}


/**
 * etchlog_get_bkuppath()
 * get a backup log file name/relative path.
 * @param outbuf buffer to receive the file name/path
 * @param outbufsize size of the out buffer, must be a/l 23 + characters plus 
 * the size of the relative path. if relative directory strings are "../logcli/" 
 * and "../logsrv/", the return string will be 32 characters including null term.
 * @param seqno the start value of the timestamp sequencer.
 * @return current sequencer on success, -1 failure. file name and relative path in outbuf.
 */
int etchlog_get_bkuppath (char* outbuf, const int outbufsize, int seqno)
{
    /* 0         1         2         3
    /* 012345678901234567890123456789012 */
    /* ../logcli/YYYYMMDDHHMMSSNNNN.log  */
    struct tm* t;
    char buf[48], *p = 0;
    const char *BKMASK = "%04d%02d%02d%02d%02d%02d%04d%s", *DOTLOG = ".log";
    time_t l; time(&l);                                
    t  = localtime(&l);
    strcpy (buf, config.calculated_is_client? ETCHCLIENTLOGDIR: ETCHSERVERLOGDIR);
    strcat (buf, "/");
    p = buf + (int) strlen(buf);

    while(1)
    {   sprintf (p, BKMASK, t->tm_year+1900, t->tm_mon+1, 
            t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, seqno, DOTLOG);
        if (!etch_existsfile(buf)) break;
        if (++seqno > 9999) return -1;
    }

    if (outbufsize < ((int) strlen(buf) + 1)) return -1;
    strcpy(outbuf, buf);
    return seqno + 1;
}


/**
 * etchlog_purge_logfiles()
 * purge files from current log directory.
 * @return count of files purged.
 */
int etchlog_purge_logfiles ()
{
    int purgedcount = 0;

    if (etch_logfiles >= config.max_log_files + ETCHCONFIGDEF_LOGCOUNT_GRACE)
    {   
        char* dirpath = etchlog_get_dirpath();
        const int purgecount = etch_logfiles - config.max_log_files;
        etchlog (ETCHLOGX, ETCHLOG_XDEBUG, "purging %d log files from %s ...\n", 
                 purgecount, dirpath);
        purgedcount = etchlog_purgefiles (dirpath, purgecount, 0);
        etchlog (ETCHLOGX, ETCHLOG_DEBUG, "purged %d log files\n", purgedcount);
        etch_logfiles -= purgedcount;
    }

    return purgedcount;
}


/**
 * etchlog_copy_logfile()
 * copy primary log file to a backup file.
 * @param is_purge_logfiles if true, and count of log files exceeds configured
 * maximum plus a grace overage, a number of log files is deleted such that the
 * log file count is brought back down to the configured maximum.
 * @remarks we may at some point want to move the log file purge to a work thread.
 * @return 0 success, -1 failure.
 */
int etchlog_copy_logfile (const int is_purge_logfiles)
{   
    char newpath[48];
    int result = -1, attempts = 0, seqno = 0;
    if (NULL == logpath) return -1;

    is_etchlog_suspended = TRUE;
    if (is_etch_logfile_open)
        fclose(flog);

    while (attempts++ < 10)  
    {   
        if (-1 == (seqno = etchlog_get_bkuppath (newpath, sizeof(newpath), seqno))) 
            break;

        if (0 != rename (logpath, newpath)) 
            continue;

        etch_logfiles++;
        etch_loglines = 0;

        if (is_etch_logfile_open)
            if (NULL == (flog = fopen(logpath, "w"))) 
                break;         

        is_etchlog_suspended = FALSE;

        if (is_purge_logfiles)  
            etchlog_purge_logfiles();

        result = 0;
        break;
    }  

    return result;
}

