/**********************************************************************
// @@@ 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 <pthread.h>
#include <time.h>
#include <signal.h>
#include <errno.h>
#include "seabed/pctl.h"
#include "ExSMGlobals.h"
#include "ExSMTask.h"
#include "ExSMReader.h"
#include "ExSMEvent.h"
#include "ExSMExitHandler.h"
#include "ComDiags.h"
#include "Globals.h"
#include "ex_exe_stmt_globals.h"
#include "ex_ex.h"
#include "ExpErrorEnums.h"
#include "ComRtUtils.h"
#include "ComSqlId.h"
#include "Statement.h"

ExSMGlobals *ExSMGlobals::smGlobals_ = NULL;
bool ExSMGlobals::smInitialized_ = false;

// The SeaMonster ID for executor internal communication will be 1.
// For example, the SHUTDOWN message from main thread to reader
// thread. The IDs assigned to queries will start at 2 and go up.
int64_t ExSMGlobals::exeInternalSMID_ = 1;
int64_t ExSMGlobals::nextAvailableSMID_ = 2;

// Counter for SM fixup replies. See comments in the header file.
uint32_t ExSMGlobals::fixupReplyCount_ = 0;

// *** THIS FUNCTION DEPENDS ON SQL CODE AND SHOULD ONLY BE CALLED
// *** FROM THE MAIN SQL THREAD. DO NOT CALL THIS FUNCTION FROM THE
// *** SM READER THREAD.
void ExSMGlobals::addDiags(const char *functionName,
                           int32_t rc,
                           ExExeStmtGlobals *stmtGlob)
{
  if (stmtGlob)
  {
    ComDiagsArea *diags = stmtGlob->getDiagsArea();
    NAMemory *diagsHeap = stmtGlob->getDefaultHeap();

    if (diags == NULL)
    {
      diags = ComDiagsArea::allocate(diagsHeap);
      stmtGlob->setGlobDiagsArea(diags);
      diags->decrRefCount();
    }

    CliGlobals *cliGlob = stmtGlob->getCliGlobals();
    const char *processName = cliGlob->myProcessNameString();

    // the nsk code determines when the error EXE_SM_FUNCTION_ERROR 
    // will be retired by AQR, for now an nsk code of 10001 and 10012
    // for error EXE_SM_FUNCTION_ERROR will be retried.
    // what codes of nsk are retried are defined in SessionDefaults.cpp file
    *diags << DgSqlCode(-EXE_SM_FUNCTION_ERROR)
           << DgString0(functionName)
           << DgInt0((Lng32) rc)
           << DgInt1((Lng32) getpid())
           << DgString1(processName)
           << DgNskCode((Lng32) 10000 + abs(rc));
  }
}

// To Do: either we need to merge addDiags and this method with a
// different name or if we want to introduce new sql error number for
// reader thread errors then this would change later to report more
// errors than just ERR_NO_SERVICE This method is currently called
// only by ex_root_tdb::build to create ERR_NO_SERVICE error and adds
// the error to stmtGlob
void ExSMGlobals::addReaderThreadError(ExExeStmtGlobals *stmtGlob)
{
  if (stmtGlob)
  {
    ComDiagsArea *diags = stmtGlob->getDiagsArea();
    NAMemory *diagsHeap = stmtGlob->getDefaultHeap();

    if (diags == NULL)
    {
      diags = ComDiagsArea::allocate(diagsHeap);
      stmtGlob->setGlobDiagsArea(diags);
      diags->decrRefCount();
    }

    CliGlobals *cliGlob = stmtGlob->getCliGlobals();
    const char *processName = cliGlob->myProcessNameString();

    *diags << DgSqlCode(-EXE_SM_FUNCTION_ERROR)
           << DgString0(readerThreadSmErrorFunction_)
           << DgInt0((Lng32) readerThreadSmErrorNumber_)
           << DgInt1((Lng32) getpid())
           << DgString1(processName)
           << DgNskCode((Lng32) 10000 + abs(-1));
  }
}


//---------------------------------------------------------------------
// Construct a string used for the trace file name.
//
// The function extracts the following fields from the SQL query ID
// 
//   CPUNUM        - the node number (SQ) where the master is running
//   PIN           - the pid of the master executor
//   EXE_STARTTIME - the start time for the master executor
//
// and concatenates them into a string like this:
//
//          000_019731_212194294688945814
// 
// The return value is the <node>_<pid>_<starttime> string
//
// The string is then used when SM trace files are created to make
// sure we can identify all the traces from the same session.
//
// Currently trace file names look like this:
//
//   <smTrcPrefix>.<nodeNumOfProcess>.<stringAbove>.<processId>.log
// 
// Example:
//
//   exsm.out.000.000_019731_212194294688945814.19731.log
//
// NOTE: the string returned is allocated on the system heap and it is
// the callers responsibility to deallocate it when it is no longer needed by 
// calling global "delete [] <str>"
//
// *** THIS FUNCTION DEPENDS ON SQL CODE AND SHOULD ONLY BE CALLED
// *** FROM THE MAIN SQL THREAD. DO NOT CALL THIS FUNCTION FROM THE
// *** SM READER THREAD.
//---------------------------------------------------------------------
const char *ExSMGlobals::createSessionID(ExExeStmtGlobals *stmtGlob)
{
  ExMasterStmtGlobals *master_glob = stmtGlob->castToExMasterStmtGlobals();
  ExEspStmtGlobals *esp_glob = stmtGlob->castToExEspStmtGlobals();

  char *sqlQueryId = NULL;
  int32_t sqlQueryIdLen = 0;

  if (master_glob != NULL)
  {
    sqlQueryId = master_glob->getStatement()->getUniqueStmtId();
    sqlQueryIdLen = master_glob->getStatement()->getUniqueStmtIdLen();   
  }
  else
  {
    sqlQueryId = esp_glob->getQueryId();
    sqlQueryIdLen = esp_glob->getQueryIdLen();
  }
 
  int32_t rc = 0;
  char *smIDStr = new char[ComSqlId::MAX_QUERY_ID_LEN];
  ex_assert(smIDStr, "Failed to allocate memory for SM session Id String");
  
  // Hack for cursors. Sometimes cursors do not have a query ID.
  if (sqlQueryIdLen == 0 )
  {
    // mkstemp replaces XXXXXX in the argument string with a value
    // that makes the file unique. mkstemp also returns an open file
    // descriptor which we don't need so we close it right away.
    char buf[32] = "Cursor_XXXXXX";
    int fd = mkstemp(buf);
    if (fd != -1)
      close(fd);

    strcpy(smIDStr, buf);
    return smIDStr;
  }
  
  // Extract fields from the query ID:
  //  Node number (CPU num in nv parlor)
  //  PID of master executor 
  //  Master executor start time

  Int64 sqNodeNumber = 0;
  Int64 masterPID = 0;
  Int64 masterStart = 0;

  if (rc == 0)
    rc = ComSqlId::getSqlQueryIdAttr(ComSqlId::SQLQUERYID_CPUNUM,
                                     sqlQueryId, sqlQueryIdLen,
                                     sqNodeNumber, NULL);
  if (rc == 0)
    rc = ComSqlId::getSqlQueryIdAttr(ComSqlId::SQLQUERYID_PIN,
                                     sqlQueryId, sqlQueryIdLen,
                                     masterPID, NULL);
  if (rc == 0)
    rc = ComSqlId::getSqlQueryIdAttr(ComSqlId::SQLQUERYID_EXESTARTTIME,
                                     sqlQueryId, sqlQueryIdLen,
                                     masterStart, NULL);

  if (rc != 0)
  {
    delete [] smIDStr;
    return NULL;
  }

  str_sprintf(smIDStr, "%d_%d_%Ld", (Int32) sqNodeNumber, (Int32) masterPID,
              (Int64) masterStart);

  return smIDStr;
}

// *** THIS FUNCTION DEPENDS ON SQL CODE AND SHOULD ONLY BE CALLED
// *** FROM THE MAIN SQL THREAD. DO NOT CALL THIS FUNCTION FROM THE
// *** SM READER THREAD.
ExSMGlobals *ExSMGlobals::InitSMGlobals(ExExeStmtGlobals *stmtGlob)
{
  int32_t rc = 0;
  bool isMasterExecutor =
    (stmtGlob->castToExMasterStmtGlobals() ? true : false);

  // The following call populates two output parameters and has no
  // other meaningful side effects. Output values are determined by
  // looking at current trace settings (passed in as arguments) and
  // the values of certain environment variables.

  uint32_t traceLevel = stmtGlob->getSMTraceLevel();
  const char *traceFilePrefix = stmtGlob->getSMTraceFilePrefix();
  uint32_t effectiveTraceLevel = 0;
  const char *effectiveTraceFilePrefix = NULL;
  ExSM_SetTraceInfo(traceLevel,       // IN
                    traceFilePrefix,  // IN
                    &effectiveTraceLevel,       // OUT
                    &effectiveTraceFilePrefix); // OUT

  // Certain initialization steps should only happen once in a given
  // process. Even if SM_init fails and we retry initialization later,
  // we only want these steps to happen once.
  static int firstTime = true;
  if (firstTime)
  {
    // Register an exit handler
    atexit(ExSM_ExitHandler);

    // Register the main thread with Seabed as pin 1
    proc_register_group_pin(0, EXSM_MAIN_THREAD_PIN);

    firstTime = false;
  }

  if (smGlobals_ == NULL)
  {
    // Note: everything in this block should be retryable. That is,
    // the block might execute again later if SM_init is not
    // successful or if the reader thread could not be created for
    // some reason. Make sure nothing is leaked if this block executes
    // again later.

    // Build the ExSMGlobals instance
    smGlobals_ = new ExSMGlobals(isMasterExecutor);
    ex_assert(smGlobals_, "ExSMGlobals allocation failure");

    // When we call SM_init we pass in a seaquest node number. Note
    // that on a workstation we often run seaquest with two virtual
    // nodes. A given seaquest process might be running on logical
    // node 0 or 1, even though all testing is taking place on a
    // single workstation.
    //
    // Two steps are needed to acquire the correct node number
    // * Ask for the "CPU number" from CLI globals. On seaquest the
    //   node number is the same as the CPU number on NV.
    // * To account for virtual nodes, pass that number through a
    //   mapping function, ExSM_GetNodeID(). The mapping is a no-op on
    //   a cluster but on a workstation will take virtual node
    //   settings into account.

    CliGlobals *cliGlobals = stmtGlob->getCliGlobals();
    int32_t cliNodeNum = (int32_t) cliGlobals->myCpu();
    smGlobals_->sqNodeNum_ = ExSM_GetNodeID(cliNodeNum);
    
    // Initialize data members in SM globals for tracing to a file.
    // The session ID string has to be generated before we initialize
    // tracing because the string becomes part of the trace file
    // name. See comments in ExSMGlobals::createSessionID() for more
    // detail on how trace file names are generated.
    smGlobals_->traceEnabled_ = (effectiveTraceLevel != 0);
    smGlobals_->traceLevel_ = effectiveTraceLevel;
    smGlobals_->traceFilePrefix_ = effectiveTraceFilePrefix;
    smGlobals_->sessionID_ = createSessionID(stmtGlob);
    ex_assert(smGlobals_->sessionID_, "Failed to create SM session ID");
    ExSM_SetTraceEnabled(smGlobals_->traceEnabled_, smGlobals_);

    // Create a thread-safe heap and IPC environment. If
    // initialization is not successful, the ExSMGlobals destructor
    // will deallocate these objects.
    NAHeap *smThreadSafeHeap = new (cliGlobals->exCollHeap())
      NAHeap("SeaMonster Threadsafe Heap",
             (NAHeap*)cliGlobals->exCollHeap(),
             (Lng32)32768,
             0 // upperLimit
             );
    smThreadSafeHeap->setThreadSafe();

    smGlobals_->threadSafeHeap_ = smThreadSafeHeap;

    EXSM_TRACE(EXSM_TRACE_INIT|EXSM_TRACE_SM_CALLS,
               "BEGIN %s, pid %d, tid %d",
               isMasterExecutor ? "MASTER" : "ESP",
               getpid(), ExSM_GetThreadID());
    EXSM_TRACE(EXSM_TRACE_INIT|EXSM_TRACE_SM_CALLS,
               "Seaquest node %d, SM node %d",
               (int) cliNodeNum, (int) smGlobals_->sqNodeNum_);
    
    // Initialize the in-memory trace. This function is a no-op if
    // called multiple times.
    ExSMEvent::initMainThread();

    // Call SM_init if it has not been done before
    if (!smInitialized_)
    {
      rc = ExSM_Initialize(smGlobals_, stmtGlob);
      if (rc == 0)
        smInitialized_ = true;
    }

    // If SM initialization failed, deallocate the SM globals object
    // and return NULL. The next call to this function will attemp SM
    // initialization again.
    if (!smInitialized_)
    {
      delete smGlobals_;
      smGlobals_ = NULL;
      return NULL;
    }
    
    // Create the reader thread
    EXSM_TRACE(EXSM_TRACE_MAIN_THR|EXSM_TRACE_INIT, 
               "Creating SM reader thread...");

    void *arg = smGlobals_;
    rc = pthread_create(&smGlobals_->readerThreadThreadId_, // thread struct
                        NULL,                 // default thread attributes
                        ExSM_ReaderFunction,  // thread start routine
                        arg);                 // arg to start routine
    EXSM_TRACE(EXSM_TRACE_MAIN_THR|EXSM_TRACE_INIT, 
               "pthread_create returned %d", rc);

    if (rc != 0)
    {
      ExSMGlobals::addDiags("InitSMGlobals: Error from pthread_create",
                            rc, stmtGlob);
      delete smGlobals_;
      smGlobals_ = NULL;
      return NULL;
    }

    EXSM_TRACE(EXSM_TRACE_MAIN_THR|EXSM_TRACE_INIT, "pthread_t %p",
               (void *) smGlobals_->readerThreadThreadId_);

  } // if (smGlobals_ == NULL)

  else
  {
    // SM globals were successfully created in a previous call to this
    // function. We still need to check if any trace information
    // changed. For example the name of the trace file might have
    // changed via a SET SESSION DEFAULT statement.

    if (smGlobals_->traceLevel_ != effectiveTraceLevel)
      smGlobals_->traceLevel_ = effectiveTraceLevel;

    bool newTracePrefix = false;
    if (strcmp(smGlobals_->traceFilePrefix_, effectiveTraceFilePrefix))
    {
      smGlobals_->traceFilePrefix_ = effectiveTraceFilePrefix;
      newTracePrefix = true;
    }

    bool newTraceEnabled = (effectiveTraceLevel != 0);
    if (newTraceEnabled != smGlobals_->traceEnabled_)
    {
      ExSM_SetTraceEnabled(newTraceEnabled, smGlobals_);
      smGlobals_->traceEnabled_ = newTraceEnabled;
    }

    if (newTracePrefix == true)
    {
      EXSM_TRACE(EXSM_TRACE_INIT, 
                 "BEGIN %s, pid %d, tid %d", 
                 isMasterExecutor ? "MASTER" : "ESP", 
                 getpid(), ExSM_GetThreadID());
    }

  } // if (smGlobals_ == NULL) else ...

  // Wait for reader thread to start
  EXSM_TRACE(EXSM_TRACE_MAIN_THR|EXSM_TRACE_INIT, "BEGIN wait for reader");
  
  struct timespec waitTime;
  clock_gettime(CLOCK_REALTIME, &waitTime);
  waitTime.tv_sec += ExSMGlobals::READER_STARTUP_WAIT;
  
  rc = pthread_mutex_lock(&smGlobals_->readerThreadStateLock_);
  exsm_assert_rc(rc, "pthread_mutex_lock");
  
  rc = 0;
  while (smGlobals_->readerThreadState_ == NOT_STARTED && rc == 0)
  {
    rc = pthread_cond_timedwait(&smGlobals_->readerThreadStateCond_,
                                &smGlobals_->readerThreadStateLock_,
                                &waitTime);
    EXSM_TRACE(EXSM_TRACE_MAIN_THR|EXSM_TRACE_INIT,
               "pthread_cond_timedwait returned %d", rc);

    // Possible errors from pthread_cond_timedwait:
    // * ETIMEDOUT -- reader thread did not initialize successfully in
    //   the specified time interval
    // * Other errors -- probably indicate a problem or a programming
    //   error in the calling thread.
    // 
    // In either case we do not want to proceed
    exsm_assert_rc(rc, "pthread_cond_timedwait");
  }
  
  rc = pthread_mutex_unlock(&smGlobals_->readerThreadStateLock_);
  exsm_assert_rc(rc, "pthread_mutex_unlock");
  
  EXSM_TRACE(EXSM_TRACE_MAIN_THR|EXSM_TRACE_INIT, "END wait for reader");
  
  return smGlobals_;
}

// *** THIS FUNCTION DEPENDS ON SQL CODE AND SHOULD ONLY BE CALLED
// *** FROM THE MAIN SQL THREAD. DO NOT CALL THIS FUNCTION FROM THE
// *** SM READER THREAD.
ExSMGlobals::ExSMGlobals(bool isMasterExecutor)
  : master_(isMasterExecutor),
    traceEnabled_(false),
    traceLevel_(0),
    traceFilePrefix_(NULL),
    sessionID_(NULL),
    smTaskList_(),
    readyList_(),
    mainThreadPID_(getpid()),
    sqNodeNum_(0),
    sendRequestCount_(0),
    sendReplyCount_(0),
    sendShortCount_(0),
    recvRequestCount_(0),
    recvReplyCount_(0),
    recvShortCount_(0),
    mainThreadThreadId_(pthread_self()),
    mainThreadState_(STARTED),
    readerThreadState_(NOT_STARTED),
    threadSafeHeap_(NULL)
{
  int rc = 0;

  // Initialize the lock and condition variable for reader thread
  // state changes
  rc = pthread_mutex_init(&readerThreadStateLock_, NULL);
  exsm_assert_rc(rc, "pthread_mutex_init");

  rc = pthread_cond_init(&readerThreadStateCond_, NULL);
  exsm_assert_rc(rc, "pthread_cond_init");
}

ExSMGlobals::~ExSMGlobals()
{
  if (sessionID_)
    delete [] sessionID_;

  if (threadSafeHeap_)
    delete threadSafeHeap_;
}

// Method to convert a ThreadState to a String - used for tracing
const char *ExSMGlobals::getThreadStateString(ThreadState ts) const
{
  switch (ts)
  {
    case NOT_STARTED: { return "NOT_STARTED"; }
    case STARTED: { return "STARTED"; }
    case DONE: { return "DONE"; }
    case PROCESSING_SHUTDOWN: { return "PROCESSING_SHUTDOWN"; }
    case TERMINATED_DUE_TO_ERROR: { return "TERMINATED_DUE_TO_ERROR"; }
    default: return ComRtGetUnknownString((Int32) ts);
  }
}

// *** THIS FUNCTION DEPENDS ON SQL CODE AND SHOULD ONLY BE CALLED
// *** FROM THE MAIN SQL THREAD. DO NOT CALL THIS FUNCTION FROM THE
// *** SM READER THREAD.
ExSMTask *ExSMGlobals::addTask(const sm_target_t &tgt,
                               uint32_t queueSize,
                               int32_t *scheduledAddr,
                               NAMemory *heap,
                               ex_tcb *tcb,
                               SMConnection *smConnection)
{
  ExSMTask *result = new ExSMTask(tgt, queueSize, scheduledAddr,
                                  heap, tcb, smConnection);
  ex_assert(result, "ExSMTask allocation failure");
  smTaskList_.addTask(result);

  EXSM_TRACE(EXSM_TRACE_PROTOCOL, "TASK ADD %p, tgt %d:%d:%" PRId64 ":%d:0x%c",
             result, (int) tgt.node, (int) tgt.pid, tgt.id,
             (int) ExSMTag_GetTagWithoutQualifier(tgt.tag),
             (char) ExSMTag_GetQualifierDisplay(tgt.tag));
  EXSM_TRACE(EXSM_TRACE_PROTOCOL, "TASK  queueSize %d, scheduledAddr %p",
             (int) queueSize, scheduledAddr);
  EXSM_TRACE(EXSM_TRACE_PROTOCOL, "TASK  tcb %p", tcb);

  return result;
}

void ExSMGlobals::removeTask(ExSMTask *t)
{
  EXSM_TRACE(EXSM_TRACE_PROTOCOL, "TASK REMOVE %p", t);
  smTaskList_.removeTask(t);
  delete t;
}

int64_t ExSMGlobals::reserveSMID()
{
  // The ID counter is 64 bits and we don't worry about wrapping around
  return nextAvailableSMID_++;
}

void ExSMGlobals::setTraceEnabled(bool b)
{
  if (!b)
  {
    // regress/executor/TEST123 expects this line of output when
    // tracing goes from ON to OFF
    EXSM_TRACE(EXSM_TRACE_MAIN_THR, "Trace disabled");
  }

  EXSM_TRACE_ENABLED = traceEnabled_ = b;
}

void ExSMGlobals::setReaderThreadState(ThreadState s,
                                       bool doLocking,
                                       bool doSignal)
{
  int rc = 0;

  if (doLocking)
  {
    rc = pthread_mutex_lock(&readerThreadStateLock_);
    exsm_assert_rc(rc, "pthread_mutex_lock");
  }

  EXSM_TRACE(EXSM_TRACE_RDR_THR, "Reader thread state %s -> %s",
             getThreadStateString(readerThreadState_),
             getThreadStateString(s));

  readerThreadState_ = s;

  if (doSignal)
  {
    rc = pthread_cond_signal(&readerThreadStateCond_);
    exsm_assert_rc(rc, "pthread_cond_signal");
  }

  if (doLocking)
  {
    rc = pthread_mutex_unlock(&readerThreadStateLock_);
    exsm_assert_rc(rc, "pthread_mutex_unlock");
  }
}

void ExSMGlobals::handleReaderThreadError(int32_t rc, 
                                          const char *function, 
                                          sm_handle_t dataHandle, 
                                          ExSMTaskList *smTaskList)
{
   if (smTaskList)
     smTaskList->unlock();

   readerThreadState_ = ExSMGlobals::TERMINATED_DUE_TO_ERROR;
   readerThreadSmErrorNumber_ = rc;
   strcpy(readerThreadSmErrorFunction_, function);
   if (dataHandle)
     rc = SM_get_done(0, dataHandle);
   XAWAKE(EXSM_MAIN_THREAD_PIN, LRABBIT);
   ExSMEvent::add(ExSMEvent::Exit);
}
