/*
 * libnqs/comms/analyzetcm.c
 *
 * DESCRIPTION:
 *
 *	Completely analyze and diagnose a transaction completion
 *	code.
 *
 *	Original Author:
 *	-------
 *	Brent A. Kingsbury, Sterling Software Incorporated.
 *	April 28, 1986.
 */

#include <libnqs/license.h>
#include <libnqs/proto.h>			/* Everyone gets this */
#include <libnqs/informcc.h>		/* NQS information completion codes */
#include <libnqs/transactcc.h>		/* NQS transaction completion codes */

#include <libsal/license.h>
#include <libsal/proto.h>
#include <libsal/defines.h>

static void exceedpreamble ( sal_debug_msg_t, char *prefix );
static void tcm_boundpreamble ( sal_debug_msg_t, char *prefix );

/*** analyzetcm
 *
 *
 *	void analyzetcm():
 *
 *	Completely analyze and diagnose a transaction completion
 *	code.
 */
void analyzetcm (
	long code,			/* Completion code */
	sal_debug_msg_t gMessType,	/* Message type */
	char *prefix)			/* Output prefix */
{

	register short reason;		/* Reason bits of completion code */

  	/* debugging checks added in 3.41.0 */
  	assert(prefix != NULL);
  
  	assert(gMessType != SAL_DEBUG_MSG_ERRORAUTHOR);
  	assert(gMessType != SAL_DEBUG_MSG_ERRORDATA);
  	assert(gMessType != SAL_DEBUG_MSG_ERRORRESOURCE);
  
	reason = (code & XCI_REASON_MASK);
	if (reason < 0 || reason > (TCM_MAXTCM & XCI_REASON_MASK) ||
	   (code & XCI_TRANSA_MASK) == 0) {
		/*
		 *  The transaction code is invalid.
		 */
		reason = (TCML_UNDEFINED & XCI_REASON_MASK);
		code = TCML_UNDEFINED;
	}
	else if (reason == (TCML_UNDEFINED & XCI_REASON_MASK)) {
		/*
		 *  Clear information bits if undefined transaction code.
		 */
		code &= ~XCI_INFORM_MASK;
	}
	/*
	 *  Analyze and describe a specific transaction code.
	 */
	tcmmsgs (code, gMessType, prefix);
	/*
	 *  Analyze and describe any additional information bits
	 *  set in the transaction completion code.
	 */
	if (reason == (TCML_QUOTALIMIT & XCI_REASON_MASK)) {
		tcimsgs (code, gMessType, prefix, exceedpreamble);
	}
	else if (reason == (TCML_SUBMITTED & XCI_REASON_MASK)) {
		tcimsgs (code, gMessType, prefix, tcm_boundpreamble);
	}
}


/*** tcm_boundpreamble
 *
 *
 *	void tcm_boundpreamble():
 *	Display bounded limit preamble.
 */
static void tcm_boundpreamble (sal_debug_msg_t gMessType, char *prefix)
{
  assert(prefix != NULL);
  
  sal_dprintf(SAL_DEBUG_INFO, gMessType, "%sIn order to successfully queue or deliver the request,\n", prefix);
  sal_dprintf(SAL_DEBUG_INFO, gMessType, "%sit was necessary to alter the following explicit request\n", prefix);
  sal_dprintf(SAL_DEBUG_INFO, gMessType, "%squota limit(s), binding them to values within the ranges\n", prefix);
  sal_dprintf(SAL_DEBUG_INFO, gMessType, "%senforceable at the execution machine:\n\n", prefix);
}


/*** exceedpreamble
 *
 *
 *	void exceedpreamble():
 *	Display limit too large to queue preamble.
 */
static void exceedpreamble (sal_debug_msg_t gMessType, char *prefix)
{
  	assert(prefix != NULL);

	sal_dprintf(SAL_DEBUG_INFO, gMessType,"%sThe request could not be queued or delivered because the\n", prefix);
	sal_dprintf(SAL_DEBUG_INFO, gMessType,"%sfollowing explicit request quota limit(s) exceeded the\n", prefix);
	sal_dprintf(SAL_DEBUG_INFO, gMessType,"%scorresponding limits of the target queue:\n\n", prefix);
}
