/*
 * libsal/debug/msgtbl.c
 * Routines to return an entry from the message table.
 * 
 * DESCRIPTION:
 * 	
 * 	The routines in this file all provide information about the
 * 	contents of the message table.  The message table is an
 * 	array which contains information about how to handle each type
 * 	of message supported by libsal.
 * 
 * 	Original Author
 * 	===============
 * 	Stuart Herbert
 * 	Academic Computng Services, University of Sheffield
 */

#include <libsal/license.h>
#include <libsal/debug/internal.h>
#include <libsal/proto.h>
#include <libsal/defines.h>
#include <syslog.h>

/*
 * !! STRUCT:	sal_debug_msgtbl_t
 * !! PURPOSE:	Structure to hold internal information about the various
 * !! PURPOSE:	debugging message types supported by libsal at this time.
 * !! PURPOSE:	This structure is not required anywhere else inside libsal
 * !! PURPOSE:	and so is not declared in any header file.
 * 
 * !! M_NAME:	iMsgType
 * !! M_TYPE:	int
 * !! M_DESC:	Contains the type of the message we are dealing with
 * 
 * !! M_NAME:	szMsgName
 * !! M_TYPE:	const char *
 * !! M_DESC:	Text name of the message type
 * 
 * !! M_NAME:	iSyslogAction
 * !! M_TYPE:	int
 * !! M_DESC:	What we tell syslog about this message
 * 
 * !! M_NAME:	iShowMessAtDebug
 * !! M_TYPE:	int
 * !! M_DESC:	At what debugging level do we show the message?
 * 
 * !! M_NAME:	iShowTraceAtDebug
 * !! M_TYPE:	int
 * !! M_DESC:	At what debugging level do we show a call-stack trace?
 * 
 * !! M_NAME:	boShowAuthorDetails
 * !! M_TYPE:	BOOLEAN
 * !! M_DESC:	Do tell the user to contact the author?
 *
 * !! M_NAME:	boShowWhere
 * !! M_TYPE:	BOOLEAN
 * !! M_DESC:	Do we tell the user where the message is in the source code?
 * 
 * !! M_NAME:	boFatal
 * !! M_TYPE:	BOOLEAN
 * !! M_DESC:	Do we abort the process?
 * 
 * !! END_STRUCT:
 */

struct sal_debug_msgtbl_t
{
  sal_debug_msg_t    	gMsgType;
  const char *		szMsgName;
  int			iSyslogAction;
  int			iShowMessAtDebug;
  int			iShowTraceAtDebug;
  BOOLEAN		boShowAuthorDetails;
  BOOLEAN		boShowWhere;
  BOOLEAN		boFatal;
};

typedef struct sal_debug_msgtbl_t sal_debug_msgtbl_t;

sal_debug_msgtbl_t stMsgTbl[] =
{
  /* TYPE			NAME			SYSLOG		MESS?	TRACE?	AUTHOR	WHERE	FATAL	*/
  { SAL_DEBUG_MSG_ERRORAUTHOR,	"Author Error  ",      	LOG_EMERG,	0,	10,	TRUE,	TRUE,	TRUE	},
  { SAL_DEBUG_MSG_ERRORRESOURCE,"Resource Error",	LOG_EMERG,	0,	10,	FALSE,	TRUE,	TRUE	},
  { SAL_DEBUG_MSG_ERRORDATA,	"Data Error    ",      	LOG_EMERG,	0,	10,	FALSE,	TRUE,	TRUE	},
  { SAL_DEBUG_MSG_WARNING,	"Warning       ",      	LOG_WARNING,	1,	10,	FALSE,	FALSE,	FALSE	},
  { SAL_DEBUG_MSG_INFO,		"Info          ",      	LOG_INFO,	1,	10,	FALSE,	FALSE,	FALSE	},
  { SAL_DEBUG_MSG_DEBUGHIGH,	"Debug (High)  ",      	LOG_DEBUG,	2,	10,	FALSE,	FALSE,	FALSE	},
  { SAL_DEBUG_MSG_DEBUGMEDIUM,	"Debug (Med)   ",      	LOG_DEBUG,	3,	10,	FALSE,	FALSE,	FALSE	},
  { SAL_DEBUG_MSG_DEBUGLOW,	"Debug (Low)   ",      	LOG_DEBUG,	4,	10,	FALSE,	FALSE,	FALSE	},
  { SAL_DEBUG_MSG_TRACE,	"Trace         ",      	LOG_DEBUG,	5,	10,	FALSE,	TRUE,	FALSE	},
  { SAL_DEBUG_MSG_INTERNAL,	"Function trace",	LOG_DEBUG,	9,	10,	FALSE,	FALSE,	FALSE	},
  { SAL_DEBUG_MSG_END,		"LIBSAL ERROR!!",	0,		0,	10,	TRUE,	TRUE,	TRUE	},
  { 0,				NULL,			0,		0,	10,	TRUE,	TRUE,	TRUE	}
};

/*
 * !! FUNCTION:	sal_debug_GetName
 * !! PURPOSE:	Call this routine with a valid message type to return
 * !! PURPOSE:	the name of the message type.
 * 
 * !! A_NAME:	gMessType
 * !! A_TYPE:	sal_debug_msg_t
 * !! A_DESC:	A valid message type
 * 
 * !! R_TYPE:	const char *
 * !! R_DESC:	Pointer to a string constant which contains the name
 * !! R_DESC:	of the message type
 * !! END_FUNCTION:
 */

const char * sal_debug_GetName
(
  sal_debug_msg_t gMessType
)
{
  TEST_ARG(gMessType > SAL_DEBUG_MSG_START, 1);
  TEST_ARG(gMessType < SAL_DEBUG_MSG_END,   1);
  
  return stMsgTbl[gMessType].szMsgName;
}

/*
 * !! FUNCTION:	sal_debug_GetSyslogAction
 * !! PURPOSE:	Call this routine with a valid message type to return
 * !! PURPOSE:	the syslog action which should be performed.
 * 
 * !! A_NAME:	gMessType
 * !! A_TYPE:	sal_debug_msg_t
 * !! A_DESC:	Message type you want to know about
 * 
 * !! R_TYPE:	int
 * !! R_DESC:	The action to pass to syslog.
 * !! END_FUNCTION:
 */

int sal_debug_GetSyslogAction
(
  sal_debug_msg_t gMessType
)
{
  TEST_ARG(gMessType > SAL_DEBUG_MSG_START, 1);
  TEST_ARG(gMessType < SAL_DEBUG_MSG_END,   1);
  
  return stMsgTbl[gMessType].iSyslogAction;
}

BOOLEAN sal_debug_QueryShowMessage
(
  sal_debug_msg_t gMessType
)
{
  TEST_ARG(gMessType > SAL_DEBUG_MSG_START, 1);
  TEST_ARG(gMessType < SAL_DEBUG_MSG_END,   1);
  
  if (sal_debug_GetLevel() >= stMsgTbl[gMessType].iShowMessAtDebug)
  {
    return TRUE;
  }
  else
  {
    return FALSE;
  }
}

BOOLEAN sal_debug_QueryShowTrace
(
  sal_debug_msg_t gMessType
)
{
  TEST_ARG(gMessType > SAL_DEBUG_MSG_START, 1);
  TEST_ARG(gMessType < SAL_DEBUG_MSG_END,   1);
  
  if (sal_debug_GetLevel() >= stMsgTbl[gMessType].iShowTraceAtDebug)
  {
    return TRUE;
  }
  else
  {
    return FALSE;
  }
}

BOOLEAN sal_debug_QueryShowAuthor
(
  sal_debug_msg_t gMessType
)
{
  TEST_ARG(gMessType > SAL_DEBUG_MSG_START, 1);
  TEST_ARG(gMessType < SAL_DEBUG_MSG_END,   1);
  
  if (stMsgTbl[gMessType].boShowAuthorDetails)
  {
    return TRUE;
  }
  else
  {
    return FALSE;
  }
}

BOOLEAN sal_debug_QueryFatal
(
  sal_debug_msg_t gMessType
)
{
  TEST_ARG(gMessType > SAL_DEBUG_MSG_START, 1);
  TEST_ARG(gMessType < SAL_DEBUG_MSG_END,   1);
  
  if (stMsgTbl[gMessType].boFatal)
  {
    return TRUE;
  }
  else
  {
    return FALSE;
  }
}

BOOLEAN sal_debug_QueryShowWhere
(
  sal_debug_msg_t gMessType
)
{
  TEST_ARG(gMessType > SAL_DEBUG_MSG_START, 1);
  TEST_ARG(gMessType < SAL_DEBUG_MSG_END,   1);
  
  if (stMsgTbl[gMessType].boShowWhere)
  {
    return TRUE;
  }
  else
  {
    return FALSE;
  }
}
