static char sccsid[]="%Z% %M% %I% %E% %U%";

#include "akbcommon.h"

static int giLOG_NO_MAX_RESV=D_LOG_NO_MAX_RESV;
static char *log_name[D_LOG_NO_MAX]=
	{"ERROR_LOG","PRINT_LOG","DEBUG_LOG","STATI_LOG","TRACE_LOG"
#ifdef NAMEX_LOG
	,"NAME5_LOG","NAME6_LOG","NAME7_LOG","NAME8_LOG","NAME9_LOG"};
#else
	,NULL,NULL,NULL,NULL,NULL};
#endif

static char *gcpLogOutBuf=NULL;
static int  giLogOutBufLen=0;

static int giLogFlg[D_LOG_NO_MAX_RESV]=
	{D_LOG_FLG_STDERR | D_LOG_FLG_FILE
	,D_LOG_FLG_STDOUT | D_LOG_FLG_FILE | D_LOG_FLG_NO_SRC
	,D_LOG_FLG_NONE
	,D_LOG_FLG_NONE
	,D_LOG_FLG_LOG_CLEAR};

static char *gcLogFile[D_LOG_NO_MAX_RESV]=
{ERROR_LOG_FILE,PRINT_LOG_FILE,DEBUG_LOG_FILE,STATI_LOG_FILE,TRACE_LOG_FILE};

static int giLogLevel[D_LOG_NO_MAX_RESV]={0,0,0,0,0};
static int giLogGrpMask[D_LOG_NO_MAX_RESV]={0,0,0x7fffff00,0,0};
static uchar gucTrace[256];
static tdtLogCtlHead *gtlh=NULL;
static int (*StatisticsCount)()=NULL;	/* (i,msglen) */
/********************************************/
/*											*/
/********************************************/
static int _akb_log_new()
{
	tdtLogCtl *tlc;
	int i;

	if (!gtlh) {
		memset(gucTrace,0,sizeof(gucTrace));
		if (gtlh = akxa_log_new(D_LOG_NO_MAX)) {
			gtlh->cur_dir = akb_akb_home(0);
			gtlh->log_max_resv = giLOG_NO_MAX_RESV;
			for (i=0;i<D_LOG_NO_MAX;i++) {
				tlc = akxa_log_get_ctl(gtlh,i);
				if (i < gtlh->log_max_resv) {
					tlc->log_flg   = giLogFlg[i];
					tlc->log_level = giLogLevel[i];
					tlc->log_grp_mask = giLogGrpMask[i];
					tlc->log_file = Strdup(gcLogFile[i]);

/*
printf("_akb_log_new: log_flg=%04x log_level=%08x log_grp_mask=%08x\n",tlc->log_flg,tlc->log_level,tlc->log_grp_mask);
*/
				}
				tlc->log_rot.rot_file_max    = 3;
				tlc->log_rot.rot_check_point = 0;
			}
		}
		else return -1;
	}
	return 0;
}

/********************************************/
/*											*/
/********************************************/
int akb_log_free()
{
	if (gtlh) {
		akxa_log_free(gtlh);
		gtlh = NULL;
	}
	if (gcpLogOutBuf) {
		Free(gcpLogOutBuf);
		gcpLogOutBuf = NULL;
	}
	return 0;
}

/********************************************/
/*											*/
/********************************************/
int akb_log_out_level_pri_main(log_no,level,file,line,pri,format,a1,a2,a3,a4,a5)
char *file,*format,*a1,*a2,*a3,*a4,*a5;
int  log_no,level,line,pri;
{
	if (_akb_log_new()) return -1;
	if (!akxa_log_flag_check(akxa_log_get_ctl(gtlh,log_no))) return 0;

	if (log_no<giLOG_NO_MAX_RESV && !akb_log_set_file_name(log_no, NULL))
		akb_log_set_file_name(log_no, gcLogFile[log_no]);

	return akxa_log_out_level_pri_main(gtlh,
		log_no,level,file,line,pri,format,a1,a2,a3,a4,a5);
}

/********************************************/
/*											*/
/********************************************/
int akb_log_out_level_main(log_no,level,file,line,format,a1,a2,a3,a4,a5)
char *file,*format,*a1,*a2,*a3,*a4,*a5;
int  log_no,level,line;
{
	return akb_log_out_level_pri_main(log_no,level,file,line,AKX_LOG_INFO,
	                             format,a1,a2,a3,a4,a5);
}

/********************************************/
/*											*/
/********************************************/
int akb_log_out_main(log_no,file,line,format,a1,a2,a3,a4,a5)
char *file,*format,*a1,*a2,*a3,*a4,*a5;
int  log_no,line;
{
	return akb_log_out_level_main(log_no,0,file,line,format,a1,a2,a3,a4,a5);
}

/********************************************/
/*											*/
/********************************************/
int akb_error_out_level_pri(level,file,line,pri,format,a1,a2,a3,a4,a5)
char *file,*format,*a1,*a2,*a3,*a4,*a5;
int  level,line,pri;
{
	akb_log_flg(D_LOG_NO_ERROR, D_LOG_FLG_PRIORITY |
	                          akb_log_flg(D_LOG_NO_ERROR,D_LOG_FLG_CHECK));

	return akb_log_out_level_pri_main(D_LOG_NO_ERROR,
	                    level,file,line,pri,format,a1,a2,a3,a4,a5);
}

/********************************************/
/*											*/
/********************************************/
int akb_error_out_level(level,file,line,format,a1,a2,a3,a4,a5)
char *file,*format,*a1,*a2,*a3,*a4,*a5;
int  level,line;
{
	return akb_log_out_level_pri_main(D_LOG_NO_ERROR,
	                    level,file,line,AKX_LOG_ERR,format,a1,a2,a3,a4,a5);
}

/********************************************/
/*											*/
/********************************************/
int akb_error_out_m(file,line,format,a1,a2,a3,a4,a5)
char *file,*format,*a1,*a2,*a3,*a4,*a5;
int  line;
{
	return akb_error_out_level(0,file,line,format,a1,a2,a3,a4,a5);
}

/********************************************/
/*											*/
/********************************************/
int akb_error_out(file,line,msg)
char *file,*msg;
int  line;
{
	return akb_error_out_m(file,line,"%s",msg,NULL,NULL,NULL,NULL);
}

/********************************************/
/*											*/
/********************************************/
int akb_debug_out_level(level,file,line,format,a1,a2,a3,a4,a5)
char *file,*format,*a1,*a2,*a3,*a4,*a5;
int  level,line;
{
	return akb_log_out_level_pri_main(D_LOG_NO_DEBUG,
	                  level,file,line,AKX_LOG_DEBUG,format,a1,a2,a3,a4,a5);
}

/********************************************/
/*											*/
/********************************************/
int akb_print_out_level(level,file,line,format,a1,a2,a3,a4,a5)
char *file,*format,*a1,*a2,*a3,*a4,*a5;
int  level,line;
{
	akb_log_flg(D_LOG_NO_PRINT, D_LOG_FLG_NO_SRC |
	                          akb_log_flg(D_LOG_NO_PRINT,D_LOG_FLG_CHECK));

	return akb_log_out_level_pri_main(D_LOG_NO_PRINT,
	                    level,file,line,AKX_LOG_INFO,format,a1,a2,a3,a4,a5);
}

/********************************************/
/*											*/
/********************************************/
char *akb_log_buf(len)
int len;
{
	if (len > 0) {
		if (gcpLogOutBuf) {
			if (len > giLogOutBufLen) {
				if (gcpLogOutBuf = Realloc(gcpLogOutBuf,len))
					giLogOutBufLen = len;
				else giLogOutBufLen = 0;
			}
		}
		else {
			if (gcpLogOutBuf = Malloc(len)) giLogOutBufLen = len;
			else giLogOutBufLen = 0;
		}
	}
	return gcpLogOutBuf;
}

/********************************************/
/*											*/
/********************************************/
int akb_log_buf_len(opt)
int opt;
{
	return giLogOutBufLen;
}

/********************************************/
/*											*/
/********************************************/
int akb_log_flg(i,f)
int i,f;
{
	if (_akb_log_new()) return -1;
	return akxa_log_flg(gtlh,i,f);
}

/********************************************/
/*											*/
/********************************************/
void akb_log_set_proc_name(cpName)
char *cpName;
{
	if (_akb_log_new()) return;
	akxa_log_set_proc_name(gtlh,cpName);
	return;
}

/********************************************/
/*											*/
/********************************************/
char *akb_log_get_proc_name()
{
	if (_akb_log_new()) return NULL;
	return akxa_log_get_proc_name(gtlh);
}

/********************************************/
/*											*/
/********************************************/
char *akb_log_set_file_name(i, cpFile)
int  i;
char *cpFile;
{
	if (_akb_log_new()) return NULL;
	return akxa_log_set_file_name(gtlh, i, cpFile);
}

/********************************************/
/*											*/
/********************************************/
int akb_get_log_time(buf,len,format)
char *buf,*format;
int  len;
{
	return akx_get_log_time(buf,len,format);
}

/********************************************/
/*											*/
/********************************************/
char *akb_log_time()
{
	return akx_log_time();
}

/********************************************/
/*											*/
/********************************************/
int akb_log_set_parm2(argc,argv,nParm,iParm)
int  argc,nParm;
long iParm[];
char *argv[];
{
	if (_akb_log_new()) return -1;
	akxa_log_set_parm2(gtlh,argc,argv,nParm,iParm);
	return 0;
}

/********************************************/
/*											*/
/********************************************/
int akb_log_set_parm(argc,argv,iParm)
int  argc;
long iParm[];
char *argv[];
{
	return akb_log_set_parm2(argc,argv,9,iParm);
}

/********************************************/
/*											*/
/********************************************/
int akb_log_from_file(logno,file)
int logno;
char *file;
{
	char buf[D_RECORD_BUFSIZE];
	char parm[D_RECORD_BUFSIZE];
	FILE *fp;
	int argc;
	char *f,*argv[9];
	int iRc;
	long iParm[10];

	f = akb_akb_home_add(file);
	if (fp = fopen(f,"r")) {
		while (akxa_read_line(buf,sizeof(buf),fp)) {
			argc = akxtgetargv2(buf,argv,9,parm,sizeof(parm),3);
			if (argc < 0) break;
			else if (argc >= 2) {
				if (!stricmp(argv[0],"srcfile")) {
					if (logno<0 || (logno>=0 && logno==atoi(argv[1])))
						iRc = akb_log_src_file(argc,argv);
				}
				else {
					if (logno<0 || (logno>=0 && logno==atoi(argv[0]))) {
						iRc = akb_log_set_parm2(argc,argv,10,iParm);
						if (iParm[6] == -2) iRc = D_ERR_MEM_ALLOC;
					}
				}
			}
		}
		fclose(fp);
	}
	else {
		ERROROUT1("akb_log_from_file:file[%s] open error.",f);
		return -1;
	}
	return 0;
}

/********************************************/
/*											*/
/********************************************/
static int __log_set_up2(c1,section,na1,na2,argv,n,pi)
char c1,*section,*na1,*na2,**argv;
int  n,*pi;
{
	char work[10];
	long iParm[10];

	if (n >= 2) {
		sprintf(work,"%d",*pi);
		argv[0] = work;
		if (!stricmp(argv[1],"-f") && n>=3) {
			akb_log_from_file(*pi,argv[2]);
		}
		else if (!stricmp(argv[1],"srcfile")) {
			argv[1] = work;
			akb_log_src_file(n,argv);
		}
		else {
			akb_log_set_parm2(n,argv,10,iParm);
			if (iParm[6] == -2) return D_ERR_MEM_ALLOC;
		}
	}
	return n;
}

/********************************************/
/*											*/
/********************************************/
int akb_log_set_up2(cpProcName)
char *cpProcName;
{
	char *argv[8],buf[81],*p,work[10],*namv[3];
	int i,n,w,len;

	namv[0] = D_SECTION_AKB_SYSTEM;
	namv[2] = cpProcName;
	for (i=0;i<giLOG_NO_MAX_RESV;i++) {
		if ((namv[1]=log_name[i]) && *namv[1]) {
			n = akb_gs_akb_stpl_func(namv,'.',"1 2 3 ",argv,8,__log_set_up2,&i);
			if (n < 0) return n;
		}
	}

	namv[1] = "LOGDIR";
	n = akb_gs_akb_stpl_func(namv,'.',"2 3 1 ",argv,2,NULL,NULL);
	if (n < 0) return n;
	else if (n >= 2)
		if (!akb_log_set_dir(argv[1])) return D_ERR_MEM_ALLOC;

	return 0;
}

/********************************************/
/*											*/
/********************************************/
char *akb_log_set_dir(cpDir)
char *cpDir;
{
	if (_akb_log_new()) return NULL;
	return akxa_log_set_dir(gtlh,cpDir);
}

/********************************************/
/*											*/
/********************************************/
int akb_log_set_up_name(cpProcName)
char *cpProcName;
{
	int ret;

	if (cpProcName && *cpProcName) akb_log_set_proc_name(cpProcName);
	ret = akb_log_set_up2(cpProcName);
	if (akb_log_flg(D_LOG_NO_TRACE,D_LOG_FLG_CHECK) & D_LOG_FLG_LOG_CLEAR)
		akb_log_clear(D_LOG_NO_TRACE,0);

	return ret;
}

/********************************************/
/*											*/
/********************************************/
int akb_log_level(i,level)
int i,level;
{
	if (_akb_log_new()) return -1;
	return akxa_log_level(gtlh,i,level);
}

/********************************************/
/*											*/
/********************************************/
int akb_log_grp_mask(i,levelbitc)
int i,levelbitc;
{
	if (_akb_log_new()) return -1;
	return akxa_log_grp_mask(gtlh,i,levelbitc);
}

/********************************************/
/*											*/
/********************************************/
int akb_log_set_src_file(pCtChg,logno,ope,setno,file,line1,line2)
tdtRbCtl *pCtChg;
char *file;
int  logno,ope,setno,line1,line2;
{
	if (_akb_log_new()) return -1;
	return akxa_log_set_src_file(gtlh,pCtChg,logno,ope,setno,file,line1,line2);
}

/********************************************/
/*  argv[0]:"srcfile"						*/
/*  argv[1]:logno							*/
/*  argv[2]:filename  / setno    > 0		*/
/*  argv[3]:line1     / filename != null	*/
/*  argv[4]:line2     / line1    > 0		*/
/*  argv[5]:          / line2    > 0		*/
/********************************************/
int akb_log_src_file(argc,argv)
int  argc;
char *argv[];
{
	if (_akb_log_new()) return -1;
	return akxa_log_src_file(gtlh,NULL,argc,argv);
}

/********************************************/
/*											*/
/********************************************/
int akb_log_out_check(log_no,level,file,line)
int  log_no,level,line;
char *file;
{
	tdtLogCtl *tlc;

	if (_akb_log_new()) return -1;
	if (!(tlc = akxa_log_get_ctl(gtlh,log_no))) return -1;
	return akxa_log_out_check(tlc,level,file,line);
}

/********************************************/
/*											*/
/********************************************/
int akbfixdmp(file,msg,dat,len)
char *file,*msg,*dat;
int len;
{
	static char *buf=NULL;
	int msglen;

	if (!msg) msg = "";
	msglen = strlen(msg) + 100;
	if (buf) buf = Realloc(buf,msglen);
	else buf = Malloc(msglen);
	if (buf) sprintf(buf,"%s %s",akb_log_time(),msg);
	return akxafixdmp(akb_akb_home_add(file),buf,dat,len);
}

/********************************************/
/*											*/
/********************************************/
int akb_log_clear(log_no,option)
int log_no,option;
{
	if (_akb_log_new()) return -1;
	return akxa_log_clear(gtlh,log_no,option);
}

/********************************************/
/*											*/
/********************************************/
int akb_log_statistics_count(i,len)
int i,len;
{
	int ret;

	if (StatisticsCount) ret = StatisticsCount(i,len);
	else ret = -1;

	return ret;
}

/********************************************/
/*											*/
/********************************************/
char *akb_log_file_path(log_no,option)
int log_no,option;
{
	if (_akb_log_new()) return NULL;
	return akxa_log_file_path(gtlh,log_no,option);
}

/********************************************/
/*											*/
/********************************************/
tdtLogCtl *akb_log_get_ctl(log_no)
int log_no;
{
	if (_akb_log_new()) return NULL;
	return akxa_log_get_ctl(gtlh,log_no);
}

/********************************************/
/*											*/
/********************************************/
int akb_log_set_command_parm(opt_c,parm_string)
char opt_c,*parm_string;
{
	static tdtGeneralData logno_set[]=
		 {{0,0,0,0,0,"l",-1}
		,{D_LOG_NO_ERROR,0,0,0,0,"e",-1}
		,{D_LOG_NO_PRINT,0,0,0,0,"p",-1}
		,{D_LOG_NO_DEBUG,0,0,0,0,"d",D_LOG_FLG_STDERR}
		};
	char opt_string[2];

	if (_akb_log_new()) return -1;
	opt_string[0] = opt_c;
	opt_string[1] = '\0';
	return akxa_log_set_command_parm(gtlh,4,logno_set,opt_string,parm_string,0);
}

/********************************/
/*								*/
/********************************/
int akb_get_log_no(name)
char *name;
{
	char **p;
	int i;

	p = log_name;
	for (i=0;*p;i++,p++) {
		if (!stricmp(name,*p)) return i;
	}
	return -1;
}

/********************************/
/*								*/
/********************************/
char *akb_get_log_name(log_no)
int log_no;
{
	char *p;
	int i;

	if (log_no<0 || log_no>=giLOG_NO_MAX_RESV) p = NULL;
	else {
		if (!(p = log_name[log_no])) p = "";
	}
	return p;
}

/********************************************/
/*											*/
/********************************************/
int akb_log_level_check(log_no,level)
int  log_no,level;
{
	tdtLogCtl *tlc;

	if (_akb_log_new()) return -1;
	if (!(tlc = akxa_log_get_ctl(gtlh,log_no))) return -1;
	return akxa_log_level_check(tlc,level);
}

/****************************************/
/*										*/
/****************************************/
int akb_prdbg_out_l5(level,file,line,fmt,a1,a2,a3,a4,a5)
int level,line;
char *file,*fmt,*a1,*a2,*a3,*a4,*a5;
{
	return  akb_anydbg_out_l5(level,D_LOG_NO_PRINT,file,line,fmt,a1,a2,a3,a4,a5);
}

/****************************************/
/*										*/
/****************************************/
int akb_errdbg_out_l5(level,file,line,fmt,a1,a2,a3,a4,a5)
int level,line;
char *file,*fmt,*a1,*a2,*a3,*a4,*a5;
{
	return  akb_anydbg_out_l5(level,D_LOG_NO_ERROR,file,line,fmt,a1,a2,a3,a4,a5);
}

/****************************************/
/*										*/
/****************************************/
int akb_anydbg_out_l5(level,i_LOG_NO_PRINT,file,line,fmt,a1,a2,a3,a4,a5)
int level,line,i_LOG_NO_PRINT;
char *file,*fmt,*a1,*a2,*a3,*a4,*a5;
{
	int log_no,sf_prn,sf_dbg,f_prn,f_dbg,l_prn,l_dbg,f,f_file,log_file,f_stdsys;
	char *pr_log_file;

	if (i_LOG_NO_PRINT == D_LOG_NO_DEBUG) {
		return akb_debug_out_level(level,file,line,fmt,a1,a2,a3,a4,a5);
	}
	else if (i_LOG_NO_PRINT == D_LOG_NO_PRINT) pr_log_file = PRINT_LOG_FILE;
	else if (i_LOG_NO_PRINT == D_LOG_NO_ERROR) pr_log_file = ERROR_LOG_FILE;
	else return -1;

	sf_prn = f_prn = LOGFLG(i_LOG_NO_PRINT,D_LOG_FLG_CHECK);
	sf_dbg = f_dbg = LOGFLG(D_LOG_NO_DEBUG,D_LOG_FLG_CHECK);
	if (i_LOG_NO_PRINT == D_LOG_NO_ERROR) f_prn &= ~D_LOG_FLG_FILE;
	l_prn = LOGLEVELCHK(i_LOG_NO_PRINT,level);
	l_dbg = LOGLEVELCHK(D_LOG_NO_DEBUG,level);
	f_stdsys = D_LOG_FLG_STDOUT | D_LOG_FLG_STDERR | D_LOG_FLG_SYSLOG;
	f = (f_prn | f_dbg) & f_stdsys;

	if (l_dbg) log_no = D_LOG_NO_DEBUG;
	else if (l_prn) log_no = i_LOG_NO_PRINT;
	else return 0;
/*
printf("akb_prdbg_out_l5: log_no=%d\n",log_no);
*/
	log_file = log_no;
	if ((f_prn & D_LOG_FLG_FILE) && (f_dbg & D_LOG_FLG_FILE)) {
		if (!stricmp(akb_log_file_path(i_LOG_NO_PRINT,0x01),
		            akb_log_file_path(D_LOG_NO_DEBUG,0x01))) {
			if ( !stricmp(akb_log_set_file_name(i_LOG_NO_PRINT,NULL),PRINT_LOG_FILE)) {
				log_file = i_LOG_NO_PRINT;
				f_file = f_prn;
			}
			else {
				log_file = D_LOG_NO_DEBUG;
				f_file = f_dbg;
			}
		}
	}
/*
printf("akb_prdbg_out_l5: log_file=%d\n",log_file);
*/
	if (log_file == D_LOG_NO_DEBUG) {
		LOGFLG(log_file,f_dbg | f);
		akb_debug_out_level(0,file,line,fmt,a1,a2,a3,a4,a5);
	}
	else {
		LOGFLG(log_file,f_prn | f);
		akb_print_out_level(0,file,line,fmt,a1,a2,a3,a4,a5);
	}

	if (log_file != log_no) {
		LOGFLG(log_file,f_file & ~f_stdsys);
		if (log_file == D_LOG_NO_DEBUG)
			akb_debug_out_level(0,file,line,fmt,a1,a2,a3,a4,a5);
		else
			akb_print_out_level(0,file,line,fmt,a1,a2,a3,a4,a5);
	}

	LOGFLG(i_LOG_NO_PRINT,sf_prn);
	LOGFLG(D_LOG_NO_DEBUG,sf_dbg);

	return 0;
}
