/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	This program is distributed in the hope that it will be 
	useful, but WITHOUT ANY WARRANTY; without even the 
	implied warranty of MERCHANTABILITY or FITNESS FOR A 
	PARTICULAR PURPOSE.

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




#ifdef VA2
#include	<varargs.h>
#else
#include	<stdarg.h>
#endif
#include	<fcntl.h>


#include	"memory_debug.h"
#include	"xl.h"
#include	"stream.h"

char log_level[LOG_MAX_LEVEL][10] = {
	"MESSAGE",
	"WARNING",
	"ERROR",
	"SYSTEM",
	"DEBUG"
};

L_CHAR * log_path;
int log_size,log_filenos;
extern L_CHAR * agent_name;

void
set_log_path(L_CHAR * str,int size,int filenos)
{
	log_path = ll_copy_str(str,1484);
	log_size = size;
	log_filenos = filenos;
}

char * get_logfile(int no)
{
char * ret;
int len;
	ret = ln_copy_str(std_cm,log_path);
	len = strlen(ret);
	ret = d_re_alloc(ret,len + 50);
	sprintf(&ret[len],"log%i",no);
	return ret;
}

void
div_logfile()
{
int fd;
char * filename1,* filename2;
int size;
int no;
	filename1 = get_logfile(0);
	fd = open(filename1,O_RDONLY);
	if ( fd < 0 )
		return;
	size = lseek(fd,0,SEEK_END);
	close(fd);
	if ( size < log_size ) {
		d_f_ree(filename1);
		return;
	}
	d_f_ree(filename1);
	filename1 = get_logfile(log_filenos-1);
	unlink(filename1);
	d_f_ree(filename1);
	for ( no = log_filenos-2 ; no >= 0 ; no -- ) {
		filename1 = get_logfile(no);
		filename2 = get_logfile(no+1);
		rename(filename1,filename2);
		d_f_ree(filename1);
		d_f_ree(filename2);
	}
}

int
log_vprintf(
	int level,
	char * fmt,
	va_list p)
{
FILE * fd;
XL_SEXP * id;
char * an;
char * buf;
char * filename;

	if ( log_path == 0 )
		return -1;
	gc_push(0,0,"log_vprintf");
	id = connect_lock(0,log_path,"write");
	if ( get_type(id) == XLT_ERROR )
		id = 0;
	div_logfile();
	filename = get_logfile(0);
	fd = fopen(filename,"a+");
	d_f_ree(filename);
	if ( fd == 0 ) {
		if ( id )
			connect_unlock(0,id->integer.data,log_path);
		gc_pop(0,0);
		return -1;
	}
	if ( agent_name )
		an = n_string(std_cm,agent_name);
	else	an = "agent??";
	if ( level >= LOG_MAX_LEVEL )
		level = LOG_SYSTEM;
	buf = get_xltime_str(get_xltime(),TFMT_UNIX);
	buf[strlen(buf)-1] = 0;
	fprintf(fd,"[%s %s (%s)] ",log_level[level],buf,an);
	vfprintf(fd,fmt,p);
	fprintf(fd,"\n");
	fclose(fd);
	d_f_ree(buf);
	if ( id )
		connect_unlock(0,id->integer.data,log_path);
	gc_pop(0,0);
	return 0;
}

int
log_printf(
	int level,
	char * fmt,...)
{
va_list p;
int ret;
#ifdef VA2
	va_start(p);
#else
	va_start(p,fmt);
#endif

	ret = log_vprintf(level,fmt,p);
	va_end(p);


	return ret;
}

int
log_print_sexp(
	int level,
	char * str,
	XL_SEXP * s,
	int flags)
{
STREAM * st;
char * d;
int ret;
	st = s_open_string_write(std_cm);
	print_sexp(st,s,flags);
	d = s_get_string(st);
	ret = log_printf(level,"%s = %s",str,d);
	s_close(st);
	return ret;
}
