/**********************************************************************
// @@@ 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 @@@
//
**********************************************************************/

#include "NAWinNT.h"

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "ErrorMessage.h"
#include "GetErrorMessage.h"

#include "ComASSERT.h"
#include "SqlciError.h"
#include "NLSConversion.h"

const size_t DEST_BUF_SIZE = 2 * ErrorMessage::MSG_BUF_SIZE;

void ErrorMessage::insertParams(NAError * errcb)
{
  if (errcb->getErrParamCount() > 0)
    {
      // Note that we allocate twice the size for tmp, in order to forestall
      // array overrun problems (i.e. memory corruption)
      NAWchar      tmp[MSG_BUF_SIZE * 2];
      NAWchar      paramName[MSG_BUF_SIZE];

      NAWchar	paramVal[MSG_BUF_SIZE];		// regular char, not TCHAR
      Int32	paramLen;
      Lng32	paramPos;
      Int32	tmpLen = 0;
      Int32	truncation = FALSE;

#pragma nowarn(1506)   // warning elimination 
      Int32	msgBufOrigLen = NAWstrlen(msgBuf_);
#pragma warn(1506)  // warning elimination 

      for (Int32 i = 0; i < msgBufOrigLen; i++)
	{
	  if (msgBuf_[i] == ERRORPARAM_BEGINMARK)
	    {
	      // Get the formal parameter name, excluding the leading '$' mark
	      NAWchar *p = paramName;
	      while (++i < msgBufOrigLen &&
	             (isalnum(msgBuf_[i]) || msgBuf_[i] == ERRORPARAM_TYPESEP))
	        *p++ = msgBuf_[i];
	      *p = NAWchar('\0');
	      i--;				// let's not lose a character!
	      paramPos = FixupMessageParam(paramName, POSITIONAL_PARAM);
	      if (paramPos >= 0)
	        {
		  paramVal[0] = NAWchar('\0');	// default is empty param
		  NAErrorParam * param = errcb->getNAErrorParam(paramPos);
		  if (param)
		    switch (param->getNAErrorParamType())
		      {
		      case NAErrorParam::NAERROR_PARAM_TYPE_INTEGER:
			NAWsprintf(paramVal,WIDE_("%d"),param->getIntegerNAErrorParam());
			break;
		      case NAErrorParam::NAERROR_PARAM_TYPE_CHAR_STRING:
			NAWsprintf(paramVal,WIDE_("%s"),param->getStringNAErrorParam());
			break;
		      }	      
#pragma nowarn(1506)   // warning elimination 
		  paramLen = NAWstrlen(paramVal);
#pragma warn(1506)  // warning elimination 

		  NAWstrncpy(&tmp[tmpLen], paramVal, paramLen);
	        }
	      else	// invalid formal param (e.g. "$ab" "$9~" "$~9" "$9x")
		{
		  tmp[tmpLen++] = ERRORPARAM_BEGINMARK;

#pragma nowarn(1506)   // warning elimination 
		  paramLen = NAWstrlen(paramName);
#pragma warn(1506)  // warning elimination 
		  NAWstrncpy(&tmp[tmpLen], paramName, paramLen);
	        }
	      tmpLen += paramLen;
	    }
	  else
	    {
	      tmp[tmpLen++] = msgBuf_[i];
	    }
	    
	  // If necessary, truncate the message and exit loop early.
	  // The -1 is for the terminating '\0' below the loop.
	  if (tmpLen > MSG_BUF_SIZE - 1)
	    {
	      tmpLen = MSG_BUF_SIZE - 1;
	      truncation = TRUE;
	      break;
	    }
	} // for

      // Indicate truncation by overwriting last three characters with '...'
      if (truncation)
	tmp[tmpLen-3] = tmp[tmpLen-2] = tmp[tmpLen-1] = NAWchar('.');

      NAWstrncpy(msgBuf_, tmp, tmpLen);
      msgBuf_[tmpLen] = NAWchar('\0');

    }

} // ErrorMessage::insertParams()

void ErrorMessage::printErrorMessage(NAError * errcb)
{
  NAWchar* tmp = msgBuf_;

  // This is always a positive number (but make sure of it!)
  NAErrorCode erc_abs = errcb->getErrCode();
  if (erc_abs < 0) erc_abs = -erc_abs;

  // A warning is positive, an error negative -- 
  // GetErrorMessage generates the proper text for each.
  NAErrorCode erc_signed = (errcb->getErrType() == NAError::NAERROR_WARNING) ?
  			   erc_abs : -erc_abs;

  NABoolean msgNotFound = GetErrorMessage(erc_signed, tmp);

  NABoolean forceParamSubst = msgNotFound && errcb->getErrParamCount() > 0;

/* 
  // if tmp was assigned to a different (e.g. a static) string, we need to copy
  // its contents into this msgBuf_ so that insertParams overwrites our copy
  // and not the original.
*/
    NAWstrcpy(msgBuf_, tmp);

  if (forceParamSubst)
    {
      // msgBuf_ will contain a suitable msg-not-found message, so now we just
      // append substitution parameters to at least make debugging easier.
      //
      // This mirrors what ComCondition::getMessageText does.
      NAWstrcat(msgBuf_, WIDE_(" $0 $1 $2 $3 $4 $5 $6 $7 $8 $9"));

      //dbg: NAWstrcat(msgBuf_, WIDE_(" $ $$ $ab $9 $~ $~~ $~0 $0~ $~a $a~ $0x $0x~int0 $int0~x # $0~int0 $int0~0 $0 $00 $0$0"));
      //dbg: NAWstrcat(msgBuf_, WIDE_(" $Int0~0$int0~1 $0~Int0$1~int0 #"));
      //dbg: NAWstrcat(msgBuf_, WIDE_(" $Int0~0$int0~0 $0~Int0$0~int0 #"));
      //dbg: NAWstrcat(msgBuf_, WIDE_(" $Int0~0$0~int0 $0~Int0$int0~0 #"));
    }

  ErrorMessageOverflowCheckW(msgBuf_, MSG_BUF_SIZE);

  insertParams(errcb);

  if (forceParamSubst)
    {
      // remove trailing blanks and unsubstituted substitution marks
#pragma nowarn(1506)   // warning elimination 
      Int32 tmpLen = NAWstrlen(msgBuf_);
#pragma warn(1506)  // warning elimination 
      while (--tmpLen >= 0 && 
      	     (msgBuf_[tmpLen] == NAWchar(' ')  || 
	      msgBuf_[tmpLen] == NAWchar('\t') ||
	      msgBuf_[tmpLen] == ERRORPARAM_BEGINMARK))
        ;
      msgBuf_[++tmpLen] = NAWchar('\0');
    }

  char msgBuf8bit[2*MSG_BUF_SIZE]; 
  UnicodeStringToLocale(CharInfo::ISO88591, msgBuf_, MSG_BUF_SIZE, msgBuf8bit, 2*MSG_BUF_SIZE);

  printf("%s\n", msgBuf8bit);

  fflush(stdout);

} // ErrorMessage::printErrorMessage()

// paramName must be passed in WITHOUT leading '$' (ERRORPARAM_BEGINMARK).
// paramName returns stripped of any internal '~' (ERRORPARAM_TYPESEP) and the
//   chars either preceding it or following it, if paramName is at all valid.
//   E.g., "0~string0" returns as "0" if positional but "string0" if named;
//   "int0~1" returns as "1" if pos but "int0" if named;
//   "2" returns as "2" either way;
//   "b" returns as "b" either way (if pos, function result is -1, invalid);
//   "intx~y" returns as "y" if pos (and function result is -1, invalid) 
//   but "intx~y" if named (with a successful result, and the ComDiagsMsg.C
//   caller will reject it as not matching a string table lookup and then
//   display the entire bogus name).
// Function returns -1 for invalid paramName,
//   0 for valid NAMED_PARAM,
//   n>=0 for valid POSITIONAL_PARAM (n = the position, 0th, 1st, 2nd, ...)
//
// Why do we need to do this?  Well, we have two kinds of messages --
// ComDiagsMsg.C ComCondition ones with named params, and
// ErrorMessage.C ErrorMessage ones with positional.
// The positional params need to have position numbers so that messages can
// be translated (I18N of text often requires reordering params).
// Tagging each param with both name and position info means that the same
// msg code can be used from anywhere (either ComDiags or E'Msg),
// i.e. we can share messages and not have a confusing welter of nearly
// identical ones.
//
Lng32 FixupMessageParam(NAWchar *paramName, MsgParamType paramType)
{
  ComASSERT(paramName);
  if (!*paramName) return -1;			// invalid (empty) paramName

  NAWchar *p;
  NAWchar* sep = NAWstrchr(paramName, ERRORPARAM_TYPESEP);

  NABoolean begend = sep ? (sep == paramName || sep[1] == NAWchar('\0')) : FALSE;

  switch (paramType)
    {
    case NAMED_PARAM:
      if (begend) return 0;			// "~x" and "9~" `legal' names
      if (sep)
	if (isdigit(*paramName))
	  NAWstrcpy(paramName, ++sep);		// "9~x" -> "x"
	else if (isdigit(sep[1]))
	  *sep = NAWchar('\0');			// "x~9" -> "x"
        //else {}				// "x~y" `legal'
      return 0;					// (Dubious legal names will be
      						// flagged by our caller.)

    case POSITIONAL_PARAM:
      if (begend) return -1;			// "~x" and "9~" invalid nums
      if (!isdigit(*paramName))
        if (!sep)
	  return -1;				// "x" invalid num
	else
	  NAWstrcpy(paramName, ++sep);		// "x~9" -> "9"
      else
        if (sep)
	  *sep = NAWchar('\0');			// "9~x" -> "9"
        //else {}				// "9" valid
      for (p=paramName; *p; p++)
        if (!isdigit(*p))
	  return -1;				// "9x" invalid num
      Lng32 pos;
      NAWsscanf(paramName, WIDE_("%d"), &pos);
      return pos;

    default:
      return -1;				// invalid (unknown paramType)
    }
} // FixupMessageParam


void FixCarriageReturn(char *str)
{
  if (! str)
    return;

  // remove any trailing \r(carriage return) or \n(line feed) from error text.
  size_t len = strlen(str);
  if (len == 0)
    return;

  if (len > 0 && str[len-1] == '\n')
    len--;
  if (len > 0 && str[len-1] == '\r')
    len--;

  if (len == 0)
    return;

  size_t j = 0;
  for (size_t i = 0; i < len; i++)
    {
      if (str[i] != '\r')
	{
	  str[j] = str[i];
	  j++;
	}
    }
  str[j] = '\0';
}

void FixCarriageReturn(NAWchar *str)
{
  // remove any trailing \r(carriage return) or \n(line feed) from error text.
  size_t len = NAWstrlen(str);
  if (len > 0 && str[len-1] == '\n')
    len--;
  if (len > 0 && str[len-1] == '\r')
    len--;

  size_t j = 0;
  for (size_t i = 0; i < len; i++)
    {
      if (str[i] != '\r')
	{
	  str[j] = str[i];
	  j++;
	}
    }
  str[j] = '\0';
}

// Changes to this function should be emulated in HandleCLIError (SqlCmd.C)
void NADumpDiags(ostream& outStream, ComDiagsArea* diags,
		 NABoolean newline,
		 Int32 commentIf,
		 FILE* fp,
		 short verbose,
                 CharInfo::CharSet terminal_cs)
{
  if (!diags) return;

  Int32 numDiags = diags->getNumber();
  
  if (!numDiags) return;

  Int32 numWarns = diags->getNumber(DgSqlCode::WARNING_);

  if ( commentIf != NO_COMMENT )
    outStream << endl;		// blank line at beginning

  if (fp) fprintf(fp, "\n");

  NABoolean sqlcodePrefixAdded = (commentIf != NO_COMMENT);
  for (Int32 i = 0; i++ < numDiags; )
  {
    NABoolean cmt = sqlcodePrefixAdded && commentIf && 
                    (commentIf < 0 || (*diags)[i].getSQLCODE() >= 0);

    if ( verbose || (!verbose) && (*diags)[i].getSQLCODE() <= 0  )
    {
     const NAWchar *msg = (*diags)[i].getMessageText(sqlcodePrefixAdded);	// NAWchar, not TCHAR
     NAWriteConsole(msg, outStream, newline, cmt, terminal_cs);

    if (fp)			// if a logfile is open, mirror messages to it
    {
      char mbstr[DEST_BUF_SIZE + 16]; 
#pragma nowarn(1506)   // warning elimination 
      UnicodeStringToLocale(terminal_cs, msg, NAWstrlen(msg),  
                            mbstr, DEST_BUF_SIZE);
#pragma warn(1506)  // warning elimination

      FixCarriageReturn(mbstr);
      fprintf(fp, "%s\n", mbstr);

      if (newline) fprintf(fp, "\n"); 
    }
    }
  }

  outStream << flush;
  if (fp) fflush(fp);
}

void NAWriteConsole(const char *str, ostream& outStream,
		    NABoolean newline,
		    NABoolean comment)
{
  if (!str) return;
  FixCarriageReturn((char *)str);
  if (comment) outStream << "--- ";
  outStream << str << endl;
  if (newline) outStream << endl;
}

void NAWriteConsole(const NAWchar *str, ostream& outStream,
		    NABoolean newline,
		    NABoolean comment,
                    CharInfo::CharSet terminal_cs)
{
  if (!str) return;
  char mbstr[DEST_BUF_SIZE + 16];

#pragma nowarn(1506)   // warning elimination 
  UnicodeStringToLocale(terminal_cs, str, NAWstrlen(str), mbstr, DEST_BUF_SIZE+16);
#pragma warn(1506)  // warning elimination 
  NAWriteConsole(mbstr, outStream, newline, comment);
}

