/*******************************************************************
  ORTCAN Project - VCA Logger
 
  vca_log.c	- simple logging support

  (C) Copyright 2002 by Pavel Pisa 

  The ORTCAN Project is distributed under the 
  Library Gnu General Public Licence. 
  See file COPYING for details.
 *******************************************************************/

//#ifndef _MSC_VER
//#include <unistd.h>
//#endif /*_MSC_VER*/
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdarg.h>
#include <can_vca.h>


int vca_debug_flg;
int vca_log_cutoff_level;   


void
vca_log_fnc_default(const char *domain, int level,
	const char *format, va_list args);

vca_log_fnc_t *vca_log_output;
FILE *vca_log_default_file;

/**
 * vca_log - generic logging facility for VCA library
 * @domain: pointer to character string representing source of logged event,
 *          it is %VCA_LDOMAIN for library itself
 * @level:  severity level
 * @format: printf style format followed by arguments
 *
 * This functions is used for logging of various events.
 * If not overridden by application, logged messages goes to the stderr.
 * Environment variable %VCA_LOG_FILENAME can be used to redirect 
 * output to file. Environment variable %VCA_DEBUG_FLG can be used
 * to select different set of logged events through vca_debug_flg.
 *
 * Note: only messages with %level <= %vca_log_cutoff_level will be logged.
 * see %can_vca.h 
 */           

void
vca_log(const char *domain, int level,
       const char *format, ...)
{
  va_list ap;
  va_start(ap, format);
  vca_vlog(domain,level,format,ap);
  va_end(ap); 
}

void
vca_vlog(const char *domain, int level,
       const char *format, va_list ap)
{
  char *s;
  if(vca_log_cutoff_level) {
      if((level & VCA_LOGL_MASK) > vca_log_cutoff_level) return;
  }
  if(vca_log_output==NULL) {
    char *log_fname;
    vca_log_output=vca_log_fnc_default;
    if((log_fname=getenv("VCA_LOG_FILENAME"))!=NULL){
      vca_log_default_file=fopen(log_fname,"a");
    }
    if(vca_log_default_file==NULL)
      vca_log_default_file=stderr;
    if(!vca_debug_flg&&((s=getenv("VCA_DEBUG_FLG"))!=NULL)){
      vca_debug_flg=atoi(s);
    }
    if((s = getenv("VCA_LOG_CUTTOFF")) != NULL) {
        vca_log_cutoff_level = atoi(s);
    }
}
  (*vca_log_output)(domain,level,format,ap);
}

/**
 * vca_log_redir - redirects default log output function
 * @log_fnc: new log output function. Value NULL resets
 *           to default function
 * @add_flags: some more flags
 */

void
vca_log_redir(vca_log_fnc_t *log_fnc, int add_flags)
{
  if(log_fnc==NULL) log_fnc=vca_log_fnc_default;
  vca_log_output=log_fnc;
}

void
vca_log_fnc_default(const char *domain, int level,
	const char *format, va_list ap)
{
  if(!(level&VCA_LOGL_CONT)) {
    level&=VCA_LOGL_MASK;
    if(level)
      fprintf(vca_log_default_file,"<%d>",level);
    if(domain)
      fprintf(vca_log_default_file,"%s: ",domain);
  }
  vfprintf(vca_log_default_file, format, ap);
  fflush(vca_log_default_file);
}


