/*
 * Debugging library routines
 */
#if defined(ENABLE_LIBYAHOO_DEBUG)

#if defined(HAVE_CONFIG_H)
#include "config.h"
#else
#define HAVE_STDARG_H
#define HAVE_STRING_H
#endif

#include "debug.h"

#include <stdlib.h>
#include <stdio.h>
#if defined(HAVE_STDARG_H)
#include <stdarg.h>
#endif

#if defined(HAVE_STRING_H)
#include <string.h>
#elif defined(HAVE_STRINGS_H)
#include <strings.h>
#endif

static FILE *debugfile = stdout;
static char *DBG_EnabledKeys[128] =
{NULL};							/* should be more than enough */
static int DBG_MaxEnabledKey = -1;

/* these routines currently do a really inneficient linear search, 
   but it's not like they need to be really fast - they are just for
   debugging purposes */

int DBG_Open(char *file)
{
	if (debugfile != stdout)
	{
		fclose(debugfile);
		debugfile = NULL;
	}

	if (!file)
	{
		fprintf(stderr, "DBG_Open Error: File is null, using stdout.\n");
		debugfile = stdout;
		return 1;
	}

	if ((debugfile = fopen(file, "a")) == NULL)
	{
		fprintf(stderr, "DBG_Open Error: Couldn't open output file.\n");
		fprintf(stderr, "                Falling back to stdout.\n");
		debugfile = stdout;
		return 1;
	}

	return 0;
}

int DBG_Disable(char *key)
{
	int i;

	if (!key)
	{
		fprintf(stderr, "DBG_Disable Error: key is null.\n");
		return 1;
	}
	for (i = 0; i <= DBG_MaxEnabledKey; i++)
	{
		if (DBG_EnabledKeys[i] && !strcmp(DBG_EnabledKeys[i], key))
		{
			free(DBG_EnabledKeys[i]);
			DBG_EnabledKeys[i] = NULL;
			return 0;
		}
	}
	return 1;
}

int DBG_Enable(char *key)
{
	int i;

	if (!key)
	{
		fprintf(stderr, "DBG_Enable Error: key is null.\n");
		return 1;
	}
	for (i = 0; i <= DBG_MaxEnabledKey; i++)
	{
		if (DBG_EnabledKeys[i] && !strcmp(DBG_EnabledKeys[i], key))
		{
			return 0;			/* already enabled */
		}
	}
	DBG_EnabledKeys[DBG_MaxEnabledKey + 1] = NULL;
	for (i = 0; i <= DBG_MaxEnabledKey + 1; i++)
	{
		if (!DBG_EnabledKeys[i])
		{
			DBG_EnabledKeys[i] = strdup(key);
			if (i > DBG_MaxEnabledKey)
			{
				DBG_MaxEnabledKey = i;
			}
			return 0;			/* already enabled */
		}
	}
	return 0;
}

int DBG_Print(char *key, char *format,...)
{
	va_list args;

	if (!key)
	{
		fprintf(stderr, "DBG_Print Error: key is null.\n");
		return 1;
	}
	if (!format)
	{
		fprintf(stderr, "DBG_Print Error: format is null.\n");
		return 1;
	}

	if (DBG_IsEnabled(key) || DBG_IsEnabled("all"))
	{
		va_start(args, format);
		vfprintf(debugfile, format, args);
		va_end(args);

		fflush(debugfile);
	}
	return 0;
}

int DBG_Close(void)
{
	if (debugfile && debugfile != stdout)
	{
		fclose(debugfile);
		debugfile = NULL;
	}
	return 0;
}

int DBG_IsEnabled(char *key)
{
	int i;

	for (i = 0; i <= DBG_MaxEnabledKey; i++)
	{
		if (!strcmp(DBG_EnabledKeys[i], key))
		{
			return 1;			/* is enabled */
		}
	}
	return 0;
}

#else

/* Debugging is not enabled, so do an inline routines that do nothing */
/* Hopefully the compiler will completely optimize these routines away */

inline int DBG_Open(char *file)
{
	return 0;
}

inline int DBG_Disable(char *key)
{
	return 0;
}

inline int DBG_Enable(char *key)
{
	return 0;
}

inline int DBG_Print(char *key, char *format,...)
{
	return 0;
}

inline int DBG_Close(void)
{
	return 0;
}

inline int DBG_IsEnabled(char *key)
{
	return 0;
}

#endif
