/**********************************************************************
// @@@ 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:         DefaultValidator.cpp
 * Description:  Validation of Defaults values.
 *
 *
 *****************************************************************************
 */

#define  SQLPARSERGLOBALS_NADEFAULTS
#define  SQLPARSERGLOBALS_FLAGS
#include "Platform.h"

#include <ctype.h>
#include <stdio.h>
#include "charinfo.h"
#include "CmpCommon.h"
#include "ComMPLoc.h"
#include "DefaultValidator.h"
#include "ObjectNames.h"
#include "SchemaDB.h"
#include "ComLocationNames.h"  // for ComIsGuardianVolumeNamePartValid()
#include "ComSqlText.h" 

#include "ComSchemaName.h" // for ComSchemaName
#include "BindWA.h"        // for extractOverrideSchemas()

#include "SqlParserGlobals.h"			// must be last


#define ERRWARN(msg)    ToErrorOrWarning(msg, errOrWarn)


void DefaultValidator::applyUpper(NAString &value) const
{
  switch (caseSensitive()) {
    case CASE_SENSITIVE:	return;
    case CASE_INSENSITIVE:	value.toUpper(); return;
    case CASE_SENSITIVE_ANSI:	{
				  // Make copy of value so we can own its data()
				  // for casting away const-ness.
				  NAString tmp(value);
				  char *s = (char *)tmp.data();
				  for (NABoolean quoted = FALSE; *s; s++) {
				    if (*s == '"')
				      quoted = !quoted;
				    else if (!quoted)
				      *s = toupper(*s);
				  }
				  value = tmp;
				  return;
    				}
    default:			CMPASSERT(FALSE);
  }
}

NAString DefaultValidator::getTypeText(DefaultValidatorType vt)
{
  switch (vt) {
    case VALID_ANY:	return "ANY";
    case VALID_INT:	return "INTEGER";
    case VALID_UINT:	return "INTEGER UNSIGNED";
    case VALID_FLT:	return "FLOAT";
    case VALID_KWD:	return "DEFAULTS-KEYWORD";
    
    default:		return "???dv???";
  }
}

Int32 DefaultValidator::validate(	  const char *,
				  const NADefaults *,
				  Int32,
				  Int32,
				  float *) const
{
  return TRUE;					// anything is valid; no error
}

Int32 ValidateKeyword::validate(	  const char *value,
				  const NADefaults *nad,
				  Int32 attrEnum,
				  Int32 errOrWarn,
				  float *) const
{
  NAString tmp(value);
  DefaultToken tok = nad->token(attrEnum, tmp, TRUE, errOrWarn);
  return (tok != DF_noSuchToken);
}





Int32 ValidateTraceStr::validate( const char       *value,
                                const NADefaults *nad,
                                Int32               attrEnum,
                                Int32               errOrWarn,
                                float            *alreadyHaveFloat) const
{
  //  const char *curr = value;

  return TRUE;
}

Int32 ValidateAnsiList::validate( const char *value,  
				const NADefaults *nad,
			 Int32 attrEnum,
			 Int32 errOrWarn,
				float *) const
{
  // Validate using a copy of "*value"
  char tempStr[1000];  // max length of ATTR_VALUE 
  if ( strlen(value) >= 1000 ) return FALSE;  // just in case
  if ( strlen(value) == 0 ) return TRUE;  // empty string ATTR_VALUE is OK
  strcpy(tempStr, value);

  // prepare to extract the partitions/tokens from the default string
  const char *token, *sep = " ,:" ;
  token = strtok( tempStr, sep );
  
  // iterate thru list of volume names; return false iff any name is invalid
  // (Also an appropriate error/warning would be issued.)
  while ( token != NULL ) {
    NAString tokenObj(token);
    Int32 countPeriods = 0, inBetween = 0;
    NABoolean anyError = tokenObj.isNull() ;
    // check three part ANSI name
    for (Int32 i = 0; !anyError && i < (Int32)tokenObj.length() ; i++ ) {
      if ( ComSqlText.isDigit(token[i]) ||
	   ComSqlText.isSimpleLatinLetter(token[i]) ) inBetween++;
      else {
	if ( ComSqlText.getPeriod() == token[i] &&  // it is a period
	     countPeriods++ < 2 ) {
	  if ( inBetween == 0 ) anyError = TRUE; // no CATALOG or SCHEMA
	  else inBetween = 0 ; // start counting the next ( SCHEMA or NAME )
	}
	else anyError = TRUE;
      }
    }
    if ( countPeriods != 2 || inBetween == 0 ) anyError = TRUE;

    if ( anyError ) {
      if (errOrWarn)
	*CmpCommon::diags() << DgSqlCode(ERRWARN(2055)) << DgString0(token) 
			    << DgString1("INVALID QUALIFIED NAME");
      return FALSE;
    }
    token = strtok( NULL, sep );
  }

  return TRUE;
}

Int32 ValidateRoleNameList::validate( const char *value,   
				const NADefaults *nad,
			 Int32 attrEnum,
			 Int32 errOrWarn,
				float *) const
{
  // Validate a list of role names.  Based on ValidateAnsiList
  // List format:  comma separated list of role names which use either . or _ 
  //  example:  "role.user1", "ROLE.user2", "role_user3"
  // SeaQuest example:  DB__Root, DB__Services, db_role12, db_user3

  // Validate using a copy of "*value"
  char tempStr[1000];  // max length of ATTR_VALUE 
  if ( strlen(value) >= 1000 ) return FALSE;  // just in case
  if ( strlen(value) == 0 ) return TRUE;  // empty string ATTR_VALUE is OK
  strcpy(tempStr, value);

  // prepare to extract the role names/tokens from the default string
  const char *token, *sep = " ," ;
  token = strtok( tempStr, sep );
  
  // iterate thru list of role names; return false iff any name is invalid
  // (Also an appropriate error/warning would be issued.)
  while ( token != NULL ) {
    NAString tokenObj(token);
    Lng32 sqlcode = ToInternalIdentifier(tokenObj, TRUE /*upCase*/,
                                         FALSE /*acceptCircumflex*/,
                                         0 /*toInternalIdentifierFlags*/);
    if (sqlcode && ABS(sqlcode) != 3128)
    {
      // 3004 A delimited identifier must contain at least one character.
      // 3118 Identifier too long.
      // 3127 Illegal character in identifier $0~string0.
      // 3128 $1~string1 is a reserved word.
      if (errOrWarn)
	*CmpCommon::diags() << DgSqlCode(ERRWARN(2055)) << DgString0(token) 
			    << DgString1("INVALID AUTHORIZATION IDENTIFIER");
    }
    token = strtok( NULL, sep );
  }

  return TRUE;
}

Int32 ValidatePOSTableSizes::validate(const char *value,
                                    const NADefaults *nad,
                                    Int32 attrEnum,
                                    Int32 errOrWarn,
                                    float *) const
{
  char tempStr[1000];  // max length of ATTR_VALUE

  if ( strlen(value) == 0 ) return TRUE;  // empty string ATTR_VALUE is OK

  if ( strlen(value) > 1000 )
  {
    *CmpCommon::diags() << DgSqlCode(ERRWARN(2055))
                        << DgString0(value)
                        << DgString1(nad->lookupAttrName(attrEnum, errOrWarn));

    return FALSE;
  }

  strcpy(tempStr, value);

  const char *token, *sep = " ,";
  token = strtok(tempStr, sep);

  float initialSize = -1;
  float maxSize = -1;
  ValidateUInt  uint;
  
  if (token != NULL)
  {
    // check if the first value is an unsigned int
    if (!uint.validate(token, nad, attrEnum, -1))
      return FALSE;
    else
    {
      sscanf(token, "%g", &initialSize);
      token = strtok(NULL, sep);
      if (token != NULL)
      {
        // check if the second value is an unsigned int
        if (!uint.validate(token, nad, attrEnum, -1))
          return FALSE;
        else
        {
          // if there is a third value or max table size is smaller than
          // initial table size raise an error
          sscanf(token, "%g", &maxSize);
          token = strtok(NULL, sep);
          if (token != NULL || maxSize < initialSize)
          {
            *CmpCommon::diags() << DgSqlCode(ERRWARN(2055))
              << DgString0(value)
              << DgString1(nad->lookupAttrName(attrEnum, errOrWarn));
  
            if (maxSize < initialSize)
            {
              *CmpCommon::diags() << DgSqlCode(ERRWARN(2077))
                << DgInt0((Lng32)maxSize)
                << DgInt1((Lng32)initialSize);
            }
            return FALSE;
          }
        }
      }
    }
  }
  else
  {
    *CmpCommon::diags() << DgSqlCode(ERRWARN(2055))
                        << DgString0(value)
                        << DgString1(nad->lookupAttrName(attrEnum, errOrWarn));

     return FALSE;
  }

  return TRUE;
}


Int32 ValidateNumericRange::validate( const char *value,
				    const NADefaults *nad,
				    Int32 attrEnum,
				    Int32 errOrWarn,
				    float *alreadyHaveFloat) const
{
  Int32 isValid = FALSE, rangeOK = FALSE, multipleOK = FALSE;
  float flt;

  if (alreadyHaveFloat)
    flt = *alreadyHaveFloat;
  else {
    isValid = nad->validateFloat(value, flt, attrEnum, SilentIfSYSTEM);
    if (isValid == SilentIfSYSTEM) return SilentIfSYSTEM;
  }

  if (alreadyHaveFloat || isValid) {

    rangeOK = (min_ <= flt && flt <= max_);
    if (rangeOK) {
      multipleOK = (multiple_ == 0 || ((ULng32)flt) % multiple_ == 0);
      if (multipleOK) {
	return TRUE;				// valid
      }
    }
  }

  if (alreadyHaveFloat) *alreadyHaveFloat = min_;

  if (errOrWarn) {

    *CmpCommon::diags() << DgSqlCode(ERRWARN(2055))
      << DgString0(value)
      << DgString1(nad->lookupAttrName(attrEnum, errOrWarn));

    if (!rangeOK) {
      char minbuf[50], maxbuf[50];
      
      if (type_ == VALID_INT) {
	sprintf(minbuf, "%d", (Lng32)min_);
	

	// A fudge factor of 64 is added for NT/Yos/Neo to include 
	// the precision lost. The value printed is 2147483520, 
	// while values are accepted till 2147483584. 
	sprintf(maxbuf, "%d", (Lng32)max_+64);
     }
      else if (type_ == VALID_UINT) {
	sprintf(minbuf, "%u", (ULng32)min_);
	if (max_ == 2147483520)
	  sprintf(maxbuf, "%u", (ULng32)max_+64);
        else
	  sprintf(maxbuf, "%u", (ULng32)max_);

      }
      else {
	sprintf(minbuf, "%g", min_);
	sprintf(maxbuf, "%g", max_);
      }

      switch (attrEnum)
        {
        case HIVE_INSERT_ERROR_MODE:
          {
            sprintf(minbuf, "%u", 0);
            sprintf(maxbuf, "%u", 3);
          }
          break;
        default:
          {
            // do nothing
          }
        }
      
      NAString range = NAString("[") + minbuf + "," + maxbuf + "]";
      *CmpCommon::diags() << DgSqlCode(ERRWARN(2056)) << DgString0(range);
    }

    if (multiple_ && !multipleOK)
      *CmpCommon::diags() << DgSqlCode(ERRWARN(2057)) << DgInt0(multiple_);

  }

  return FALSE;					// not valid
}

//-----------------------------------------------------------------------------
// ValidateCollationList:
//	The motivation for this class is as a temporary STOPGAP measure
//	in MX-NSK-Rel1, to (half)support MP COLLATEd columns.
//	See the MP_COLLATIONS default attr, the ReadTableDef code that
//	also calls the insertIntoCDB (CollationDB) method below, and
//	the "SYNTAX OF THE MP_COLLATIONS LIST" comments below.
//
//	A more fully fledged support would require a new ReadTableDef request
//	to garner information about the collation from the MP CPRULES table,
//	namely, a) validation that the collation exists,
//	b) the CPRULES.CHARACTERISTICS value,
//	c) CPRULES.CHARACTERSET value.
//-----------------------------------------------------------------------------

Int32 ValidateCollationList::validate(const char *value,
				    const NADefaults *nad,
				    Int32 attrEnum,
				    Int32 errOrWarn,
				    float *) const
{
  if (errOrWarn) {
    CMPASSERT(nad && attrEnum);
    errOrWarn = +1;			// warnings only (else silent)
  }

  // Cast away constness on various private members which are really implicit
  // arguments (the validate method by itself vs. from insertIntoCDB).
  ValidateCollationList *ncThis = (ValidateCollationList *)this;

  #ifndef NDEBUG
    if (getenv("NCHAR_DEBUG")) ncThis->formatRetry_ = TRUE;
  #endif

  // If cdb is NULL, we are validating only; if nonNULL, we are inserting.
  CollationDB *cdb = ncThis->cdb_;
  const ComMPLoc   *defaultMPLoc  = NULL;
  const SchemaName *defaultSchema = NULL;
  if (cdb) {
    CMPASSERT(sdb_);
    defaultMPLoc  = &SqlParser_MPLOC;
    defaultSchema = &sdb_->getDefaultSchema();
  }

  // Make our own copy of the value string data,
  // on which we can safely cast away const-ness for the loop,
  // which chops the list up into individual names by replacing
  // (in place, i.e. w/o additional copying)
  // each semicolon with a string-terminating nul.
  NAString collNAS(value);
  char *collList = (char *)collNAS.data();

  while (*collList) {

    // SYNTAX OF THE MP_COLLATIONS LIST:
    //
    // The list may look like any of these:
    //	''		(empty)
    //	'collname'
    //	'c1; sv.c2; $v.sv.c3; \s.$v.sv.c4'
    //	'c1; sv.c2; $v.sv.c3; \s.$v.sv.c4;'
    //	' = c1; =sv.c2;=$v.sv.c3;\s.$v.sv.c4;'
    // We also ignore pathologies like
    //	'   '  or  '=========;;;;;===;    ; =  = == =; ; ; '
    //
    // The '=' flags the following collation name as one that has a 1:1 mapping,
    // i.e. its CPRULES.CHARACTERISTICS == 'O',
    // i.e. in Rel1 it allows only equality comparisons
    //      (SQL '=', '<>', DISTINCT, GROUP BY),
    // although no other operations
    // (other predicates, ordering, MIN/MAX, partitioning)
    // would be disallowed -- the column wouldn't even be updatable,
    // but it could be at least read and appear in some limited other places.
    //
    // The absence of a '=' means the collation's CHARACTERISTICS == 'N',
    // and in Rel1 we cannot support *any* comparisons, predicates, MIN/MAX,
    // ordering, partitioning, on it --
    // it's basically just a name attached to a column,
    // but the intent was to allow the column to be at least readable.
    //
    // See ReadTableDef and NATable to see if MP COLLATEd column support
    // is or is not currently being enabled.

    // Find the next semicolon separator outside of delim-ident quotes,
    // or find end of string.
    // Set collStr to be the fragment up to (excluding) the semicolon or zero;
    // set collList to be the rest of itself (after the semicolon).
    //
    char *s = collList;
    for (NABoolean quoted = FALSE; *s; s++) {
      if (*s == '"')
	quoted = !quoted;
      else if (*s == ';' && !quoted)
	break;
    }
    char sep = *s;			// sep is either ';' or '\0'
    *s = '\0';
    NAString collStr(collList);
    collList = sep ? ++s : s;		// get past ';' OR stay on final '\0'
    
    CollationInfo::CollationFlags flags = CollationInfo::ALL_CMP_ILLEGAL;

    TrimNAStringSpace(collStr);		// remove leading/trailing blanks
    size_t i = 0, n = collStr.length();
    while (i < n)
      if (collStr[i] == '=' || collStr[i] == ' ')
	i++;				// get past leading '=' (and blanks)
      else
        break;
    if (i) {				// an '=' was seen, EQ_NE_CMP is LEGAL
      flags = CollationInfo::ORDERED_CMP_ILLEGAL;
      collStr.remove(0, i);
    }

    if (!collStr.isNull()) {
      NABoolean ok = FALSE;
      NABoolean nsk = formatNSK_;
      NABoolean retry = formatRetry_;

      retry_as_other_format:

	if (nsk) {
	  ComMPLoc collMP(collStr, ComMPLoc::FILE);
	  if (collMP.isValid(ComMPLoc::FILE)) {
	    ok = TRUE;
	    if (cdb) {
	      ncThis->lastCoInserted_ =
	        cdb->insert(collMP, defaultMPLoc, flags);
	    }
	  }
	}
	else {
	  ComObjectName collMX(collStr);
	  if (collMX.isValid()) {
	    ok = TRUE;
	    if (cdb) {
	      QualifiedName collQN(collMX);
	      ncThis->lastCoInserted_ =
	        cdb->insert(collQN, defaultSchema, flags);
	    }
	  }
	}

      if (ok) ncThis->cntCoParsed_++;

      if (!ok && retry) {
        retry = FALSE;			// Retry only once,
	nsk = !nsk;			// using the other name format.
	goto retry_as_other_format;
      }

      if (!ok && errOrWarn)
	*CmpCommon::diags() << DgSqlCode(ERRWARN(2055))
	    << DgString0(collStr)
	    << DgString1(nad->lookupAttrName(attrEnum, errOrWarn));

    }	// !collStr.isNull()
  } // while

  return TRUE;				// warnings only; all is valid
}

UInt32 ValidateCollationList::insertIntoCDB(SchemaDB *sdb,
					      CollationDB *cdb,
					      const char *value,
					      NABoolean nsk)
{
  NABoolean savformatNSK = formatNSK_;
  formatNSK_ = nsk;

  lastCoInserted_ = CharInfo::UNKNOWN_COLLATION;
  cntCoParsed_ = 0;

  CMPASSERT(!cdb_ && !sdb_);	// our kludgy/dodgy passing mechanism...
  cdb_ = cdb;
  sdb_ = sdb;
  validate(value, NULL, 0, 0/*silent*/);
  cdb_ = NULL;
  sdb_ = NULL;

  formatNSK_ = savformatNSK;

  #ifndef NDEBUG
    if (getenv("NCHAR_DEBUG")) CollationDB::Display();
  #endif

  return cntCoParsed_;
}

// validate OVERRIDE_SCHEMA FROM_SCHEMA:TO_SCHEMA setting
// format validation for xxx:yyy
Int32 ValidateOverrideSchema::validate( const char *value,
                                    const NADefaults *nad,
                                    Int32 attrEnum,
                                    Int32 errOrWarn,
                                    float *flt ) const
{
  NABoolean ok = TRUE;
  Int32 len = strlen(value);

  if (len == 0)                             // empty is ok
    return ok;

  NAString fromSchema, toSchema;

  extractOverrideSchemas(value, fromSchema, toSchema);

  if ( (fromSchema.isNull()) || (toSchema.isNull()) )
    ok = FALSE;  
  else
  {
    ComSchemaName targetSchema(toSchema);
    if (!targetSchema.isValid())
      ok = FALSE;
    else
      if (fromSchema!="*")  // reserve * for wildcard operation
      {
        ComSchemaName sourceSchema(fromSchema);
        if (!sourceSchema.isValid())
          ok = FALSE; 
      }
  }
 
  if (!ok && errOrWarn)
    *CmpCommon::diags() << DgSqlCode(ERRWARN(2055))
	<< DgString0(value)
	<< DgString1(nad->lookupAttrName(attrEnum, errOrWarn));

  return ok;

}

// validate PUBLIC_SCHEMA_NAME setting
// setting may be schema or catalog.schema
Int32 ValidatePublicSchema::validate( const char *value,
                                    const NADefaults *nad,
                                    Int32 attrEnum,
                                    Int32 errOrWarn,
                                    float *flt ) const
{
  NABoolean ok = TRUE;
  Int32 len = strlen(value);

  if (len == 0)                             // empty is ok
    return ok;

  ComSchemaName pubSchema(value);
  if (!pubSchema.isValid())
    ok = FALSE;
 
  if (!ok && errOrWarn)
    *CmpCommon::diags() << DgSqlCode(ERRWARN(2055))
	<< DgString0(value)
	<< DgString1(nad->lookupAttrName(attrEnum, errOrWarn));

  return ok;

}

// validate REPLICATE_IO_VERSION setting
// setting may be schema or catalog.schema
Int32 ValidateReplIoVersion::validate( const char *value,
                                    const NADefaults *nad,
                                    Int32 attrEnum,
                                    Int32 errOrWarn,
                                    float *alreadyHaveFloat ) const
{
  Int32 isValid = FALSE;
  float flt;
  Int32 min;

  if (alreadyHaveFloat)
    flt = *alreadyHaveFloat;
  else {
    isValid = nad->validateFloat(value, flt, attrEnum, SilentIfSYSTEM);
    if (isValid == SilentIfSYSTEM) return SilentIfSYSTEM;
  }

  if (alreadyHaveFloat || isValid) 
  {
    if (Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL))
       min = 1;
    else
       min = min_; 
    if (flt >= min && flt <= max_)
       return TRUE;                            // valid
  }

  if (alreadyHaveFloat) *alreadyHaveFloat = (float)min_;

  if (errOrWarn)
    *CmpCommon::diags() << DgSqlCode(ERRWARN(2055))
        << DgString0(value)
        << DgString1(nad->lookupAttrName(attrEnum, errOrWarn));

  return FALSE;

}

// validate parameter for MV_AGE
Int32 ValidateMVAge::validate( const char *value,
                               const NADefaults *nad,
                               Int32 attrEnum,
                               Int32 errOrWarn,
                               float *alreadyHaveFloat ) const
{
  Int32 isOK = FALSE;
  float number=0;
  char textChars[20];

  if (strlen(value) < 15)
  {
    if (sscanf(value, "%f %s", &number, textChars) == 2)
    {
      const NAString text(textChars);
      if (!text.compareTo("Seconds", NAString::ignoreCase))
      {
	isOK = TRUE;
      }
      else if (!text.compareTo("Minutes", NAString::ignoreCase))
      {
	isOK = TRUE;
      }
      else if (!text.compareTo("Hours", NAString::ignoreCase))
      {
	isOK = TRUE;
      }
      else if (!text.compareTo("Days", NAString::ignoreCase))
      {
	isOK = TRUE;
      }
    }
  }

  if (!isOK)
  {
    if (errOrWarn)
      *CmpCommon::diags() << DgSqlCode(ERRWARN(2055))
          << DgString0(value)
          << DgString1(nad->lookupAttrName(attrEnum, errOrWarn));
  }
  
  return isOK;
}
