// **********************************************************************
// @@@ 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 "QueryRewriteServer.h"
#include "QmmQmm.h"
#include "QRSharedPtr.h"
#include "QRLogger.h"
#include "NAType.h"

#if defined (NA_LINUX)
#include "nsk/nskport.h"
#include "seabed/ms.h"
#include "seabed/fs.h"
extern void my_mpi_fclose();
#include "SCMVersHelp.h"
DEFINE_DOVERS(tdm_arkqmm)
#endif

/**
 * \file
 * Contains the main() function for the Query Matching Monitor (QMM) executable.
 * The initial instance of QMM is a Guardian persistent process (the "head QMM"),
 * which starts the remaining QMMs and the Query Matching Publisher (QMP). The 
 * QMP determines the number of QMSs for each QMM to start and passes this info
 * to the head QMM, which forwards it to the other QMMs. The QMMs create their
 * respective pools of QMS processes, spreading them across CPUs to enhance
 * parallelism. There is one QMM for a given number of CPUs (divisible by the
 * size of a segment).
 *
 * QMMs have published names, which allows MXCMPs to contact them if they are
 * unable to use their local QMS and need to be allocated one.
 */

using namespace QR;

#define XML_BUFF_SIZE 32768
static NAHeap qmmHeap("QMM Heap",
                      NAMemory::DERIVED_FROM_SYS_HEAP,
                      (Lng32)131072);

/**
 * Reads command-line arguments passed to QMM. Returns the selected values for
 * the cpu to start QMP on, how or if it is to be started, and whether to listen
 * for events with receive() or waitOnAll(). Defaults should be assigned to these
 * variables before calling; they are not set if the corresponding argument does
 * not appear on the command line.
 *
 * @param argc Number of arguments on the command line.
 * @param argv Array of arguments.
 * @param [out] qmpCpu The cpu number to start the QMP process on.
 * @param [out] startOpt Indicator of how QMP is to be started, if at all.
 * @param [out] listenOpt Whether to doreceive() or waitOnAll().
 */
static void processCommandLine(Int32 argc, char *argv[],
                               short& qmpCpu, StartOpt& startOpt,
                               ListenOpt& listenOpt)
{
  Int32 currArg = 1;
  while (currArg < argc)
  {
    if (!stricmp(argv[currArg], "-qmpcpu"))
      {
        currArg++;
        assertLogAndThrow(CAT_QMM, LL_ERROR,
                          currArg < argc, QmmException,
                          "Cpu number did not follow \"-qmpcpu\"");
        qmpCpu = atoi(argv[currArg]);
        if (qmpCpu < 0 || qmpCpu > CPUS_PER_SEGMENT - 1)
          qmpCpu = IPC_CPU_DONT_CARE;
        currArg++;
      }
    else if (!stricmp(argv[currArg], "-start"))
      {
        currArg++;
        assertLogAndThrow(CAT_QMM, LL_ERROR,
                          currArg < argc, QmmException,
                          "Start option did not follow \"-start\"");
        if (!stricmp(argv[currArg], "spawn"))
          startOpt = SPAWN;
        else if (!stricmp(argv[currArg], "server"))
          startOpt = SERVER;
        else if (!stricmp(argv[currArg], "none"))
          startOpt = NONE;
        else
          assertLogAndThrow1(CAT_QMM, LL_ERROR,
                             FALSE, QmmException,
                             "Invalid value for \"-start\" parameter -- %s",
                             argv[currArg])
        currArg++;
      }
    else if (!stricmp(argv[currArg], "-listen"))
      {
        currArg++;
        assertLogAndThrow(CAT_QMM, LL_ERROR,
                          currArg < argc, QmmException,
                          "Start option did not follow \"-listen\"");
        if (!stricmp(argv[currArg], "receive"))
          listenOpt = RECEIVE;
        else if (!stricmp(argv[currArg], "waitonall"))
          listenOpt = WAITONALL;
        else if (!stricmp(argv[currArg], "waitcc"))
          listenOpt = WAITCC;
        else
          assertLogAndThrow1(CAT_QMM, LL_ERROR,
                             FALSE, QmmException,
                             "Invalid value for \"-listen\" parameter -- %s",
                             argv[currArg])
        currArg++;
      }
    else
      assertLogAndThrow1(CAT_QMM, LL_ERROR,
                         FALSE, QmmException,
                         "Unrecognized parameter -- %s", argv[currArg])
  }
} // processCommandLine

// This is needed to avoid a link error.
NABoolean NAType::isComparable(const NAType &other,
                               ItemExpr *parentOp,
                               Int32 emitErr) const
{ return FALSE; }

static short getDefaultQmpCpu(const IpcEnvironment* ipcEnv)
{
  short qmpCpu;

#ifdef NA_WINNT
  qmpCpu = 0;
#elif defined(NA_LINUX)

  // Default QMP location is the same cpu QMM is running on.
  SB_Phandle_Type procHandle;
  Int32 lc_cpu;
  XPROCESSHANDLE_GETMINE_(&procHandle);
  short error = XPROCESSHANDLE_DECOMPOSE_ (&procHandle, &lc_cpu);
  qmpCpu = lc_cpu;

  if (error)
    {
      QRLogger::log(CAT_QMM, LL_ERROR,
                               "XPROCESSHANDLE_DECOMPOSE_ returned error %d", error);
      qmpCpu = 3;  // best-guess default
    }
#endif

  return qmpCpu;
}


#ifdef NA_LINUX
extern "C"
{
Int32 sq_fs_dllmain();
}
#endif


Int32 main(Int32 argc, char *argv[])
{

#ifdef NA_LINUX
  dovers(argc, argv);

  try
  {
    file_init_attach(&argc, &argv, TRUE, (char *)"");
    sq_fs_dllmain();
    msg_debug_hook("tdm_arkqmm", "tdm_arkqmm.hook");
    file_mon_process_startup(true);
    atexit(my_mpi_fclose);
  }
  catch (...)
  {
    cerr << "Error while initializing messaging system. Exiting..." << endl;
    exit(1);
  }
#endif

  Lng32 result = 0;

  QRLogger::instance().setModule(QRLogger::QRL_QMM);
  QRLogger::instance().initLog4cxx("log4cxx.qmm.config");

  QRLogger::log(CAT_QMM, LL_INFO,
    "Command-line QMM invoked with %d arguments.", argc);
  //for (int i=0; i<argc; i++)
  //  debugMessage2("Program argument %d is %s", i, argv[i]);
   
#ifdef NA_WINNT
  if (getenv("QMP_MSGBOX_PROCESS") != NULL)
  {
    MessageBox( NULL, "QMM Process Launched", (CHAR *)argv[0], MB_OK|MB_ICONINFORMATION );
  };
#endif

  Qmm* qmm = NULL;
  try
    {
      qmm = Qmm::getInstance(&qmmHeap);

      // Get default startup arguments. Must do this before processing command
      // line args, which may override these values.
      StartOpt startOpt = SPAWN;
      ListenOpt listenOpt = WAITCC;
      short qmpCpu = getDefaultQmpCpu(qmm->getEnvironment());

      processCommandLine(argc, argv, qmpCpu, startOpt, listenOpt);
      qmm->setListenOpt(listenOpt);
      qmm->setQmpStartOpt(startOpt);
      #ifndef NA_WINNT
      qmm->allocateQmsPool();
      qmm->checkAndRetryQms();
      #else
      qmm->allocateQms();
      #endif
      qmm->startQmp(qmpCpu);
    }
  catch (QmmException& ex)
    {
      QRLogger::log(CAT_QMM, LL_ERROR,
        "QMM initialization failed: %s", ex.getMessage());
      return -1;
    }
  catch (...)
    {
      QRLogger::log(CAT_QMM, LL_ERROR,
        "QMM initialization failed: unknown exception occurred");
      return -1;
    }

  if (qmm)
    {
      QRLogger::log(CAT_QMM, LL_INFO,
        "QMM initialization complete, waiting for messages...");
      qmm->executeMessageLoop();
    }
  else
    QRLogger::log(CAT_QMM, LL_ERROR,
      "QMM exiting; creation of instance failed, no exception thrown.");

}  // main

