/*
 * Verbose/debug output functions
 *
 * Copyright (C) 2003--2007  Enrico Zini <enrico@debian.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 */

#include "util/output.h"
#include <wibble/sys/mutex.h>

#include <cstdio>
#include <cstdarg>
#include <cstdlib>
#include <syslog.h>

using namespace std;

namespace util {

static Output* instance = 0;
static wibble::sys::Mutex outputMutex;

Output& Output::get() throw ()
{
	if (!instance)
		instance = new Output;
	return *instance;
}
	
Output::Output() throw ()
	: _verbose(false), _debug(false), _syslog(false) {}

}

using namespace util;

void fatal_error(const char* fmt, ...) ATTR_PRINTF(1, 2)
{
	wibble::sys::MutexLock lock(outputMutex);

	fprintf(stderr, "guessnet: ");
	va_list ap;
	va_start(ap, fmt);
	vfprintf(stderr, fmt, ap);
	if (Output::get().syslog())
	{
		va_start(ap, fmt);
		vsyslog(LOG_INFO, fmt, ap);
	}
	va_end(ap);
	fprintf(stderr, "\n");
	exit(1);
}

void error(const char* fmt, ...) ATTR_PRINTF(1, 2)
{
	wibble::sys::MutexLock lock(outputMutex);

	va_list ap;
	va_start(ap, fmt);
	vfprintf(stderr, fmt, ap);
	if (Output::get().syslog())
	{
		va_start(ap, fmt);
		vsyslog(LOG_INFO, fmt, ap);
	}
	va_end(ap);
}

void warning(const char* fmt, ...) ATTR_PRINTF(1, 2)
{
	wibble::sys::MutexLock lock(outputMutex);

	va_list ap;
	va_start(ap, fmt);
	vfprintf(stderr, fmt, ap);
	if (Output::get().syslog())
	{
		va_start(ap, fmt);
		vsyslog(LOG_INFO, fmt, ap);
	}
	va_end(ap);
}

void output(const char* fmt, ...) ATTR_PRINTF(1, 2)
{
	wibble::sys::MutexLock lock(outputMutex);

	va_list ap;
	va_start(ap, fmt);
	vfprintf(stdout, fmt, ap);
	va_end(ap);
}

void verbose(const char* fmt, ...) ATTR_PRINTF(1, 2)
{
	wibble::sys::MutexLock lock(outputMutex);

	if (Output::get().verbose())
	{
		va_list ap;
		va_start(ap, fmt);
		fprintf(stderr, "guessnet: ");
		vfprintf(stderr, fmt, ap);
		if (Output::get().syslog())
		{
			va_start(ap, fmt);
			vsyslog(LOG_INFO, fmt, ap);
		}
		va_end(ap);
	}
}

void debug(const char* fmt, ...) ATTR_PRINTF(1, 2)
{
	wibble::sys::MutexLock lock(outputMutex);

	if (Output::get().debug())
	{
		va_list ap;
		va_start(ap, fmt);
		fprintf(stderr, "guessnet: ");
		vfprintf(stderr, fmt, ap);
		if (Output::get().syslog())
		{
			va_start(ap, fmt);
			vsyslog(LOG_INFO, fmt, ap);
		}
		va_end(ap);
	}
}

// vim:set ts=4 sw=4:
