/**********************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/

/* -*-C++-*-
 *****************************************************************************
 *
 * File:         GetErrorMessage.cpp
 * Description:
 *
 * Created:      2/23/96
 * Modified:     $ $Date: 2007/10/09 19:40:40 $ (GMT)
 * Language:     C++
 *
 *
 *****************************************************************************
 */



#include "Platform.h"
#include <ctype.h>
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>


#include "GetErrorMessage.h"
#include "ErrorMessage.h"
#include "NAWinNT.h"

#include "sqlmxmsg_msg.h"

#include "NLSConversion.h"
#include "ExSMCommon.h"

#include <fcntl.h>
#include <signal.h>	
#include <nl_types.h>

// ----------------------------------------------------
// Definitions common to both _WINDOWS and non-WINDOWS.
// ----------------------------------------------------

// UR2
static const NAWchar
  MsgFile_Not_Found[] = WIDE_("*** ERROR[16000] Error message file not found."),
  Msg_Not_Found[]     = WIDE_("No message found for SQLCODE $0~sqlcode."),
  Error_Pfx[]	      = WIDE_("*** ERROR[%d] "),
  Warning_Pfx[]       = WIDE_("*** WARNING[%d] "),
  Info_Pfx[]	      = WIDE_("*** INFO[%d] "),
  Effect_Pfx[]	      = WIDE_("\nEFFECT:\n"),
  Success_Msg[]       = WIDE_("*** INFO[0] Successful completion.\n"),
  Cause_Pfx[]	      = WIDE_("\nCAUSE:\n"),
  Recovery_Pfx[]      = WIDE_("\nRECOVERY:\n");

// UR2. Used by getErrorMessage, NSK version
static const char
  Msg_Not_Found_NSK[] = "No message found for SQLCODE $0~sqlcode.";

const Int32 SQLSTATE_LEN = 5;	// per Ansi
const Int32 HELPID_LEN   = 5;	// per SQL/MX
const Int32 EMS_SEVERITY_LEN = 5;     // per SQL/MX
const Int32 EMS_EVENT_TARGET_LEN   = 7;     // per SQL/MX
const Int32 EMS_EXPERIENCE_LEVEL_LEN   = 8;     // per SQL/MX

static NABoolean isInfoSQLSTATE(const NAWchar* state) 
{
  Int32 i = SQLSTATE_LEN;
  for (; i--; )
    if (*state++ != '0') break;
  if (i < 0) return TRUE;		// SQLSTATE was "00000"
  // ComASSERT(*--state != ' ');
  return FALSE;
}

// Following is the implementation of the SQLSTATE-related functions.
class SqlstateInfo
{
public:
  SqlstateInfo(Lng32 sqlcode, char * sqlstate, NABoolean fabricatedSqlstate)
       : sqlcode_(sqlcode), sqlstate_(NULL),
	 fabricatedSqlstate_(fabricatedSqlstate)
  {
    if (sqlstate)
      {
	sqlstate_ = new char[6];
	strcpy(sqlstate_, sqlstate);
      }
  };

  ~SqlstateInfo()
  {
    if (sqlstate_)
      delete sqlstate_;
  };

  Lng32 sqlcode() { return sqlcode_; };
  char * sqlstate() { return sqlstate_; };
  NABoolean fabricatedSqlstate() { return fabricatedSqlstate_;};

  // -------------------------------------------------------------------------
  // Since a SqlstateInfo is an index, it has an automatic conversion operator
  // to type CollIndex.
  // -------------------------------------------------------------------------
  operator CollIndex () const { return sqlcode_; };


private:
  Lng32 sqlcode_;
  char * sqlstate_;
  NABoolean fabricatedSqlstate_;
};

static NAList<SqlstateInfo*> listOfSqlstates_(NULL);
static pthread_mutex_t       listOfSqlstates_mutex = PTHREAD_MUTEX_INITIALIZER;

NABoolean GetSqlstateInfo(Lng32 sqlcode, char * sqlstate,
			  NABoolean &fabricatedSqlstate)
{
  //SqlstateInfo ssi(sqlcode, NULL, TRUE);
  //CollIndex i = listOfSqlstates_.index(&ssi);

  NABoolean found = FALSE;
  CollIndex i = 0;

  (void) pthread_mutex_lock( &listOfSqlstates_mutex );
  while ((i < listOfSqlstates_.entries()) &&
	 (NOT found))
    {
      if (listOfSqlstates_[i]->sqlcode() == sqlcode)
	found = TRUE;
      else
	i++;
    }

  if (found) //i != NULL_COLL_INDEX)
    {
      SqlstateInfo * s = listOfSqlstates_[i];
      str_cpy_all(sqlstate, s->sqlstate(), 6);
      fabricatedSqlstate = s->fabricatedSqlstate();
    }
  (void) pthread_mutex_unlock( &listOfSqlstates_mutex );
  return found;
}

void AddSqlstateInfo(Lng32 sqlcode, char * sqlstate,
		     NABoolean fabricatedSqlstate)
{
  SqlstateInfo * s = NULL;
  s = new SqlstateInfo(sqlcode, sqlstate, fabricatedSqlstate);

  (void) pthread_mutex_lock( &listOfSqlstates_mutex );
  listOfSqlstates_.insert(s);
  (void) pthread_mutex_unlock( &listOfSqlstates_mutex );
}

// See sqlci/Define.cpp for this
static short needToBindToMessageFile = TRUE;
void GetErrorMessageRebindMessageFile() { needToBindToMessageFile = TRUE; }

// Trivial global function, just hides our message format from caller:
// Get past the "...] " and return pointer to rest of the text.
char *GetPastHeaderOfErrorMessage(char *text)
{
  while (*text)
    if (*text++ == ']')
      break;
  while (*text && isspace((unsigned char)*text))   // For VS2003
    text++;
  return text;
}


// Some static data and function followed by the accessor global function
static const size_t MAX_MSGFN_LEN = 60;

//
// NOTE: The variable msgfn_Ptr_ is made THREAD_P because different
//       Compiler threads might use a different Error Message file name
//       but it is believed that two Compiler instances within the same
//       thread would share the same Error Message file name.
//
static THREAD_P const char  *msgfn_Ptr_ = NULL;
//
// NOTE: The msgfn_Buf_ array is being left as global 'static' because
//       it holds a filename matching the SQLMX_MESSAGEFILE environment
//       variable and that should be the same for all Compiler threads.
//
static       char   msgfn_Buf_[MAX_MSGFN_LEN];

static void saveErrorMessageFileName(const char *nam, NABoolean fromGetEnv)
{
  if (!fromGetEnv)
    msgfn_Ptr_ = nam;
  else {
    msgfn_Ptr_ = msgfn_Buf_;
    size_t len = strlen(nam) + 1;	// +1 to include the final '\0'
    strncpy(msgfn_Buf_, nam, MINOF(MAX_MSGFN_LEN, len));

    if (len > MAX_MSGFN_LEN) {
      // Truncate the name in the buffer.  Yes, sizeof includes the final '\0'.
      static const char ellipsis[] = " ...";
      strcpy(&msgfn_Buf_[MAX_MSGFN_LEN - sizeof(ellipsis)], ellipsis);
    }
  }
}

const char *GetErrorMessageFileName()	// global func
{
  if (!msgfn_Ptr_) {
    NAWchar *s;
    GetErrorMessage(1, s);		// force a saveErrorMessageFileName()
  }
  return msgfn_Ptr_;
}

// ----------------------------------------------------

NABoolean openMessageCatalog(nl_catd* msgCatalog)
{ 
    #define MAX_MESSAGE_PATH_LEN 1024
    char defaultMessageFile[MAX_MESSAGE_PATH_LEN];
    defaultMessageFile[0] = '\0';

    char *mySQROOT          = getenv("TRAF_HOME");
    const char *msgCatPath2 = "/export/bin";
    const char *mbType      = getenv("SQ_MBTYPE");
    const char *msgCatPath4 = "/mxcierrors.cat";

    if (mbType == NULL)  // happens in older builds
      mbType = "32";

    snprintf(defaultMessageFile, MAX_MESSAGE_PATH_LEN, "%s%s%s%s",
             mySQROOT, msgCatPath2, mbType, msgCatPath4);
    
  // Note that SQLMX_MESSAGEFILE is usually set via ms.env, so the above is not relevant  
  const char *cat = getenv("SQLMX_MESSAGEFILE");
  if (!cat)   cat = defaultMessageFile;
  saveErrorMessageFileName(cat, cat != defaultMessageFile);

//BEGIN Solution number 10-040729-8360 
  sigset_t mask_set;	/* used to set a signal masking set. */
 
  sigemptyset(&mask_set);
  sigaddset(&mask_set,SIGINT);
  sigaddset(&mask_set,SIGQUIT);

  sigprocmask(SIG_BLOCK, &mask_set , NULL);
  *msgCatalog = catopen(cat, 0);
  sigprocmask(SIG_UNBLOCK, &mask_set , NULL);
  //END Solution number 10-040729-8360 

  if (!msgCatalog)              // The simulated catopen is really fopen...
    return FALSE;
  else 
    return TRUE;
}

NABoolean getErrorMessageFromCatalog(NAErrorCode error_code_abs, 
                                     MsgTextType M_type,
                                     NAWchar* msgBuf, Lng32 msgBufLen
                                     , nl_catd* msgCatalog
                                     )
{
  Int32 set_num;

  set_num = ((error_code_abs/10) * 10);

  // map M_type to the linenum offset in error.cat file.
  // ERROR_TEXT, SQL_STATE, HELP_ID are all available at
  // offset 1 (first line).
  Lng32 offset = 0;
  switch (M_type)
    {
    case ERROR_TEXT:
    case SQL_STATE:
    case HELP_ID:
    case EMS_SEVERITY:
    case EMS_EVENT_TARGET:
    case EMS_EXPERIENCE_LEVEL:
      offset = 1;
      break;

    case CAUSE_TEXT:
      offset = 2;
      break;

    case EFFECT_TEXT:
      offset = 3;
      break;

    case RECOVERY_TEXT:
      offset = 4;
      break;
    }

  NAErrorCode error_code_ix = (4 * (error_code_abs - set_num)) + offset;



  //BEGIN Solution number 10-040729-8360 
  //The second call of catgets dumps if the previous call has been interrupted. 
  sigset_t mask_set;	/* used to set a signal masking set. */
 
  sigemptyset(&mask_set);
  sigaddset(&mask_set,SIGINT);
  sigaddset(&mask_set,SIGQUIT);

  sigprocmask(SIG_BLOCK, &mask_set , NULL);
  char *msg = catgets(*msgCatalog, set_num, error_code_ix, Msg_Not_Found_NSK);

  sigprocmask(SIG_UNBLOCK, &mask_set , NULL);
  //END Solution number 10-040729-8360 


 // The catgets routine returns a pointer to default message if no
 // message was found for a certain error number.
  NABoolean result = (msg == Msg_Not_Found_NSK) ? FALSE : TRUE;

  // convert to Unicode
  Lng32 wMsgLen = LocaleStringToUnicode(CharInfo::ISO88591, 
                        msg, strlen(msg), msgBuf, msgBufLen);


  if ( wMsgLen == 0 )
     result = FALSE;

  return result ;
}

short GetErrorMessage (Lng32 error_code,
		       NAWchar *& return_text,
		       MsgTextType M_type,
		       NAWchar* alternate_return_text,
		       Int32 recurse_level, NABoolean prefixNeeded)
{

  short msgNotFound = TRUE;			// assume error return

  NAErrorCode error_code_abs = error_code;
  if (error_code_abs < 0)
    error_code_abs = -error_code_abs;		// absolute value

  //
  // This Gotten_MsgFile_Not_Found variable is made THREAD_P because 
  // different Compiler threads could be for different users.  We
  // should keep track on a per-user basis whether or not we have
  // previously put out a 'Msg File not found' message.
  //
  static THREAD_P short Gotten_MsgFile_Not_Found = FALSE;

  //
  // Different Compiler threads may need different msg_buf arrays, but
  // there should be no chance of invoking another Compiler instance
  // within the same thread while this buffer's contents are important.
  //
  static THREAD_P NAWchar msg_buf[ErrorMessage::MSG_BUF_SIZE];

  NAWchar *s = msg_buf;
  if (alternate_return_text) s = alternate_return_text;

  switch (M_type)
    {
    case ERROR_TEXT:
      {
          if ( prefixNeeded == TRUE ) {
		if (error_code < 0)
		  NAWsprintf(s, Error_Pfx, error_code_abs);
		else if (error_code > 0)
		  NAWsprintf(s, Warning_Pfx, error_code_abs);
		else
		  NAWsprintf(s, Info_Pfx, error_code_abs);
          } else
	    *s = 0;
          break;
      }
    case CAUSE_TEXT:
      {
		NAWsprintf(s, Cause_Pfx);
		break;
      }
    case EFFECT_TEXT:
      {
		NAWsprintf(s, Effect_Pfx);
		break;
      }
    case RECOVERY_TEXT:
      {
		NAWsprintf(s, Recovery_Pfx);
		break;
      }
    case SQL_STATE:
    case HELP_ID:
    case EMS_SEVERITY:
    case EMS_EVENT_TARGET:
    case EMS_EXPERIENCE_LEVEL:
      {
		// Don't need a header for SQLSTATE or HELP_ID..
		// However, ensure that msg_buf is empty
		*s = 0;
		break;
      }
    };

  NAWchar *s_orig = s;
  s += NAWstrlen(s);

  static NABoolean initialized = FALSE;
	
//
// msgCatalog is left as a global 'static' because, once it is initialized,
// it is never changed and all threads should be able to share it.
// This assumes that all threads will use the same msg catalog.
// We use a mutex to prevent more than one thread from trying to initialize
// it concurrently and the variable 'initialized' to prevent subsequent
// initializations after the first one.
//
  static nl_catd msgCatalog;
	
  if (!initialized) // Don't go for the mutex in initialization already done
  {
     static pthread_mutex_t openMsgCatMutex = PTHREAD_MUTEX_INITIALIZER;

     int rc = pthread_mutex_lock(&openMsgCatMutex);
     exsm_assert_rc( rc, "pthread_mutex_lock" );

     // Just in case the initialization happened in another thread while
     // we were waiting for the mutex, we recheck 'initialized'.
     //
     if ( ! initialized )
     {
        if ( openMessageCatalog(&msgCatalog) == FALSE )
        {
           // The message catalog could not be opened.
           // (Displayed only once per sqlci session.)
           if (!Gotten_MsgFile_Not_Found)
              NAWsprintf(s, WIDE_("\n%s"),  MsgFile_Not_Found);
           else
              NAWsprintf(s, WIDE_("\n"));
           Gotten_MsgFile_Not_Found = TRUE;
        } // openMessageCatalog == FALSE 
        else {
           initialized = TRUE;
        }
     }  // initialized

     rc = pthread_mutex_unlock(&openMsgCatMutex);
     exsm_assert_rc( rc, "pthread_mutex_unlock" );

  } // initialized

  NAWchar msg[ErrorMessage::MSG_BUF_SIZE];

  if  ( getErrorMessageFromCatalog(error_code_abs, M_type,  
                                  msg, ErrorMessage::MSG_BUF_SIZE
                                  , &msgCatalog
                                 ) == FALSE )
  {
    // No message found, just return the default message...
    // only if we are looking for the error message.
    if (M_type == ERROR_TEXT)
      {
	if (recurse_level == 0)
	  {
	    if (error_code == 0)
	      {
  		s = msg_buf;
		NAWsprintf(s, Success_Msg);
	      }
	    else
	      {
		NAWsprintf(s++, WIDE_("\n"));
		GetErrorMessage(-SQLERRORS_MSG_NOT_FOUND, s, ERROR_TEXT, s, 1);
	      }
	  }
	else
	  NAWsprintf(s, WIDE_("%s"), Msg_Not_Found);
      }
      else
	NAWsprintf(s, WIDE_("\n"));
    }
  else	// Message found
    {
      NAWchar *msgPtr = msg;

      if (M_type == SQL_STATE)
	{
	      // Return text starting at the SQLSTATE
	      NAWstrncpy(s, msgPtr, SQLSTATE_LEN);
	      s[SQLSTATE_LEN] = 0;	// Null terminate the buffer.
	}
      else if (M_type == HELP_ID)
	{
	      // Get past the SQLSTATE field
	      // and return text starting at the HELPID
	      msgPtr += SQLSTATE_LEN + 1;	// +1 for delimiting space
	      NAWstrncpy(s, msgPtr, HELPID_LEN);
	      s[HELPID_LEN] = 0;
	}
      else if (M_type == EMS_EXPERIENCE_LEVEL)
        {
	      // Get past the SQLSTATE and HELP_ID fields
	      // and return text starting at the EMS_EXPERIENCE_LEVEL
	      msgPtr += SQLSTATE_LEN + 1 + HELPID_LEN + 1;	// +1 for delimiting space
	      NAWstrncpy(s, msgPtr, EMS_EXPERIENCE_LEVEL_LEN);
	      s[EMS_EXPERIENCE_LEVEL_LEN] = 0;
        }
      else if (M_type == EMS_SEVERITY)
        {
	      // Get past the SQLSTATE, HELP_ID and EMS_EXPERIENCE_LEVEL fields
	      // and return text starting at the EMS_SEVERITY 
	      msgPtr += SQLSTATE_LEN + 1 + HELPID_LEN + 1 + EMS_EXPERIENCE_LEVEL_LEN + 1;	// +1 for delimiting space
	      NAWstrncpy(s, msgPtr, EMS_SEVERITY_LEN);
	      s[EMS_SEVERITY_LEN] = 0;
        }
      else if (M_type == EMS_EVENT_TARGET)
        {
	      // Get past the SQLSTATE, HELP_ID, EMS_EXPERIENCE_LEVEL and EMS_SEVERITY fields
	      // and return text starting at the EMS_EVENT_TARGET
	      msgPtr += SQLSTATE_LEN + 1 + HELPID_LEN + 1 + EMS_EXPERIENCE_LEVEL_LEN + 1
                                     + EMS_SEVERITY_LEN + 1;	// +1 for delimiting space
	      NAWstrncpy(s, msgPtr, EMS_EVENT_TARGET_LEN);
	      s[EMS_EVENT_TARGET_LEN] = 0;
        }
      else
	{
	      if (s != s_orig && isInfoSQLSTATE(msg))
	        {
		  s = s_orig;
		  NAWsprintf(s, Info_Pfx, error_code_abs);
  		  s += NAWstrlen(s);
		}

	      // Get past the SQLSTATE, HELP_ID, EMS_EXPERIENCE_LEVEL, EMS_SEVERITY, and 
	      // EMS_EVENT_TARGET fields and return only the message text.
	      msgPtr += SQLSTATE_LEN + 1 + HELPID_LEN + 1 + EMS_SEVERITY_LEN + 1 
                                     + EMS_EVENT_TARGET_LEN + 1 + EMS_EXPERIENCE_LEVEL_LEN + 1;
	      NAWsprintf(s, WIDE_("%s"), msgPtr);
	}

      msgNotFound = FALSE;			// success, message found
    }

  return_text = msg_buf;

  if (alternate_return_text) return_text = alternate_return_text;

  ErrorMessageOverflowCheckW(return_text, ErrorMessage::MSG_BUF_SIZE);

  return msgNotFound;

} // GetErrorMessage


// These two platform-dependent clones of GetErrorMessage could be
// enormously simplified by using the appropriate #defines from NAWinNT.h ...


//
// The variable kludgeMessageFileText is a pointer to a 'const' string.
// The pointer can change, but only once.  It is a global 'static'
// because it is believed that all threads can share the same string
// once it is set.  Also, it is used only in Debug-Mode builds.
//
static const char *kludgeMessageFileText = NULL;

static short kludgeReadStraightFromMessageFile
	       (Lng32 num, NAWchar *msgBuf, Lng32 bufSize)
{
#ifdef NDEBUG
  return FALSE;
#else
  // A kludge for when the message DLL is completely gone:
  // use 100K of system heap to read in as much of SqlciErrors.txt
  // as we can, and do string lookup on that to find messages.
  //
  static const char emptyText = '\0';
  if (!kludgeMessageFileText) {				// first time in
    kludgeMessageFileText = &emptyText;
    const char *env = getenv("SQLMX_MESSAGEFILE");	// /bin/SqlciErrors.txt
    saveErrorMessageFileName(env, !!env);
    if (!env) return FALSE;
    Int32 fd = open(env, O_RDONLY);
    if (fd < 0) return FALSE;


    struct stat stbuf;

    if (fstat(fd, &stbuf) != 0)
       return FALSE;

    char *buffer = new char[stbuf.st_size + 2]; // For prefix sentinel and trailing null
    if (!buffer) return FALSE;
    buffer[0] = '\n';					// prefix sentinel

    size_t i = 1;
    size_t num_left = stbuf.st_size;    
    size_t nread;

    while ((nread = read(fd, &buffer[i], (num_left < 8192 ? num_left : 8192))) != 0)
    {
      i += nread;
      num_left -= nread;
    }
    buffer[i] = '\0';
    kludgeMessageFileText = buffer;
    close(fd);
  }
  if (!*kludgeMessageFileText) return FALSE;
  char numAscii[20];
  sprintf(numAscii, "\n%d ", num);
  const char *msg = strstr(kludgeMessageFileText, numAscii);
  if (!msg) { *msgBuf = -1; return FALSE; }		// nonzero: msgfile fnd
  msg += strlen(numAscii);
  UInt32 i = 0;
  for (; i < bufSize; i++) { // cvt char* to WCHAR*
    char c = msg[i];
    if (c == '\n' || c == '\r') break;
    msgBuf[i] = c;
  }
  msgBuf[i] = '\0';
  return TRUE;						// message found
#endif
} // kludgeReadStraightFromMessageFile

void GetPreprocessorInstallPath(char *thePath, char *CorCOBOL)
{
} // GetPreProcessorInstallPath


NABoolean openMessageCatalog()
{
  return 0;
}

short GetErrorMessageRC(Lng32 num, NAWchar* msgBuf, Lng32 bufSize)
{
    return kludgeReadStraightFromMessageFile(num, msgBuf, bufSize);
 // return TRUE;
} // GetErrorMessageRC



void ErrorMessageOverflowCheckW (NAWchar *buf, size_t max)
{
  size_t len = NAWstrlen(buf);
  if (len > max-1)			// max-1, to allow for terminal '\0'
    {
      cerr << endl << "ERROR: msg overflow " << len << " " << max-1 << endl;

      char* buf8bit = new char[len+1];
      Lng32 l = UnicodeStringToLocale(CharInfo::ISO88591, buf, len, 
                                     buf8bit, len+1);
      if ( l != len )
         ABORT("Unicode To Locale Translation");  

      printf("%s\n", buf8bit);
      ABORT("ErrorMessageOverflowCheck");  // memory overrun/corruption, unsafe to continue
    }
}
