/* debug.c
 *
 * vim:smartindent ts=8:sts=2:sta:et:ai:shiftwidth=2
 ****************************************************************
 * Copyright (C) 2005 Canonical Limited
 *     Authors: Robert Collins <robert.collins@canonical.com>
 *
 * See the file "COPYING" for further information about
 * the copyright and warranty status of this work.
 *
 * The bulk of this file was extracted from squid. The original
 * copyright statement follows.
 *
 * DEBUG: section 0     Debug Routines
 * AUTHOR: Harvest Derived
 *
 * SQUID Web Proxy Cache          http://www.squid-cache.org/
 * ----------------------------------------------------------
 *
 *  Squid is the result of efforts by numerous individuals from
 *  the Internet community; see the CONTRIBUTORS file for full
 *  details.   Many organizations have provided support for Squid's
 *  development; see the SPONSORS file for full details.  Squid is
 *  Copyrighted (C) 2001 by the Regents of the University of
 *  California; see the COPYRIGHT file for full details.  Squid
 *  incorporates software developed and/or copyrighted by other
 *  sources; see the CREDITS file for full details.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *  
 *  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.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
 *
 */

#include "config-options.h"
#include "po/gettext.h"
#include "hackerlab/bugs/panic.h"
#include "hackerlab/os/stdarg.h"
#include "hackerlab/os/errno-to-string.h"
#include "hackerlab/char/str.h"
#include "hackerlab/vu/safe.h"
#include "hackerlab/vu/safe-printfmt.h"
#include "libdate/date-string.h"
#include "libarch/debug.h"


/**
 * \broef an array of debug sections, and the verbosity level
 * of that section.
 * you can think of this as a chattiness level:
 * the higher the number, the more detail is show
 */
int arch_debug_levels[MAX_DEBUG_SECTIONS];
/**
 * \brief the debug level for the current message being output
 */
int arch_debug_level;

static char *debug_log_file = NULL;
static int debug_log = -1;
//static const char *debugLogTime(time_t);
static void _db_print_stderr(const char *format, va_list args);
static void _db_print_file(const char *format, va_list args);
static void arch_db_init(const char *logfile, const char *options);
/* what debug level stdout should be capped at. 
 * levels about this will only go to file by default
 */
int opt_debug_stderr = 1;

#define BUFSIZ 4096

void
arch_db_print(const char *format,...)
{
    /* disabled for now */ 
#if enableme
    t_uchar *datestr;
#endif
    va_list args1;
    va_list args2;
    va_start(args1, format);
    va_start(args2, format);
#if enableme
    datestr = pretty_date (curtime());
    safe_printfmt (2, );
    snprintf(f, BUFSIZ, "%s| %s",
	debugLogTime(squid_curtime),
	format);
#endif
    /* Add other debug targets here */
    _db_print_file(format, args1);
    _db_print_stderr(format, args2);
    va_end(args1);
    va_end(args2);
#if enableme
    lim_free (0, datestr);
#endif
}

static void
_db_print_file(const char *format, va_list args)
{
    if (debug_log < 0)
	return;
    /* 2 == stderr */
    if (debug_log == 2)
	return;
    safe_printfmt_va_list(debug_log, format, args);
    safe_flush(debug_log);
}

static void
_db_print_stderr(const char *format, va_list args)
{
    if (opt_debug_stderr < arch_debug_level)
	return;
    safe_printfmt_va_list (2, format, args);
}

static void
debugArg(const char *arg)
{
    int s = 0;
    int l = 0;
    int i;
    if (!str_casecmp_n(arg, 3, "ALL", 3)) {
	s = -1;
	arg += 4;
    } else {
	s = atoi(arg);
	while (*arg && *arg++ != ',');
    }
    l = atoi(arg);
    invariant(s >= -1);
    invariant(s < MAX_DEBUG_SECTIONS);
    if (l < 0)
	l = 0;
    if (l > 10)
	l = 10;
    if (s >= 0) {
	arch_debug_levels[s] = l;
	return;
    }
    for (i = 0; i < MAX_DEBUG_SECTIONS; i++)
	arch_debug_levels[i] = l;
}

static void
debugOpenLog(const char *logfile)
{
    int errn;
    if (logfile == NULL) {
	debug_log = 2;
	return;
    }
    /* keep a local copy */
    debug_log_file = str_replace (debug_log_file, str_save (0, logfile));
    if (debug_log > -1 && debug_log != 2)
	safe_close(debug_log);
    debug_log = vu_open(&errn, (t_uchar *)logfile, O_CREAT| O_APPEND | O_WRONLY, 0666);
    if (debug_log < 0) {
	safe_printfmt(2, "WARNING: Cannot write log file: %s\n", logfile);
        safe_printfmt(2, "%s\n", errno_to_string (errn));
	safe_printfmt(2, "         messages will be sent to 'stderr'.\n");
	safe_flush(2);
	debug_log = 2;
    }
}

#define w_space " \t"

void
arch_db_init(const char *logfile, const char *options)
{
    int i;
    char *p = NULL;
    t_uchar *s = NULL;

    for (i = 0; i < MAX_DEBUG_SECTIONS; i++)
	arch_debug_levels[i] = -1;

    if (options) {
        t_uchar * cur;
	p = str_save (0, options);
        s = p;
	for (cur = str_separate(&s, w_space); cur; cur = str_separate(&s, w_space))
	    debugArg(cur);
	lim_free(0, p);
    }
    else {
        /* defaults */
        debugArg ("ALL,1");
    }
    debugOpenLog(logfile);
}

extern char ** environ;
/**
 * \brief setup debug logging
 * magic config routine
 */
void
arch_debug_init()
{
    char *options = NULL;
    char *file = NULL;
    int x;
    for (x = 0; environ[x]; ++x)
      {
        if (!str_cmp_prefix ("ARCH_DEBUG_OPTIONS=", environ[x]))
            options = str_chr_index (environ [x], '=') + 1;
        else if (!str_cmp_prefix ("ARCH_DEBUG_LOG=", environ[x]))
          {
            file = str_chr_index (environ [x], '=') + 1;
          }
      }
    arch_db_init (file, options);
}


syntax highlighted by Code2HTML, v. 0.9.1