//===-- MICmdBase.cpp -------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// In-house headers:
#include "MICmdBase.h"
#include "MICmdArgValConsume.h"
#include "MICmdArgValOptionLong.h"
#include "MICmnLLDBDebugSessionInfo.h"
#include "MICmnMIValueConst.h"

//++
//------------------------------------------------------------------------------------
// Details: CMICmdBase constructor.
// Type:    Method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmdBase::CMICmdBase()
    : m_pSelfCreatorFn(nullptr),
      m_rLLDBDebugSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()),
      m_bHasResultRecordExtra(false), m_constStrArgThreadGroup("thread-group"),
      m_constStrArgThread("thread"), m_constStrArgFrame("frame"),
      m_constStrArgConsume("--"), m_ThreadGrpArgMandatory(false),
      m_ThreadArgMandatory(false), m_FrameArgMandatory(false) {}

//++
//------------------------------------------------------------------------------------
// Details: CMICmdBase destructor.
// Type:    Overrideable.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmdBase::~CMICmdBase() {}

//++
//------------------------------------------------------------------------------------
// Details: The invoker requires this function.
// Type:    Overridden.
// Args:    None.
// Return:  SMICmdData & -  *this command's present status/data/information.
// Throws:  None.
//--
const SMICmdData &CMICmdBase::GetCmdData() const { return m_cmdData; }

//++
//------------------------------------------------------------------------------------
// Details: The invoker requires this function.
// Type:    Overridden.
// Args:    None.
// Return:  CMIUtilString & -   *this command's current error description.
//                              Empty string indicates command status ok.
// Throws:  None.
//--
const CMIUtilString &CMICmdBase::GetErrorDescription() const {
  return m_strCurrentErrDescription;
}

//++
//------------------------------------------------------------------------------------
// Details: The CMICmdFactory requires this function. Retrieve the command and
// argument
//          options description string.
// Type:    Overridden.
// Args:    None.
// Return:  CMIUtilString & -   Command description.
// Throws:  None.
//--
const CMIUtilString &CMICmdBase::GetMiCmd() const { return m_strMiCmd; }

//++
//------------------------------------------------------------------------------------
// Details: Help parse the arguments that are common to all commands.
// Args:    None.
// Return:  None
// Throws:  None.
//--
void CMICmdBase::AddCommonArgs() {
  m_setCmdArgs.Add(new CMICmdArgValOptionLong(
      m_constStrArgThreadGroup, m_ThreadGrpArgMandatory, true,
      CMICmdArgValListBase::eArgValType_ThreadGrp, 1));
  m_setCmdArgs.Add(new CMICmdArgValOptionLong(
      m_constStrArgThread, m_ThreadArgMandatory, true,
      CMICmdArgValListBase::eArgValType_Number, 1));
  m_setCmdArgs.Add(
      new CMICmdArgValOptionLong(m_constStrArgFrame, m_FrameArgMandatory, true,
                                 CMICmdArgValListBase::eArgValType_Number, 1));
  m_setCmdArgs.Add(new CMICmdArgValConsume(m_constStrArgConsume, false));
}

//++
//------------------------------------------------------------------------------------
// Details: The invoker requires this function. A command must be given working
// data and
//          provide data about its status or provide information to other
//          objects.
// Type:    Overridden.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
void CMICmdBase::SetCmdData(const SMICmdData &vCmdData) {
  m_cmdData = vCmdData;
}

//++
//------------------------------------------------------------------------------------
// Details: The command factory requires this function. The factory calls this
// function
//          so it can obtain *this command's creation function.
// Type:    Overridden.
// Args:    None.
// Return:  CMICmdFactory::CmdCreatorFnPtr - Function pointer.
// Throws:  None.
//--
CMICmdFactory::CmdCreatorFnPtr CMICmdBase::GetCmdCreatorFn() const {
  return m_pSelfCreatorFn;
}

//++
//------------------------------------------------------------------------------------
// Details: If a command is an event type (has callbacks registered with
// SBListener) it
//          needs to inform the Invoker that it has finished its work so that
//          the
//          Invoker can tidy up and call the commands Acknowledge function (yes
//          the
//          command itself could call the Acknowledge itself but not doing that
//          way).
// Type:    Overridden.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
void CMICmdBase::CmdFinishedTellInvoker() const {
  CMICmdInvoker::Instance().CmdExecuteFinished(const_cast<CMICmdBase &>(*this));
}

//++
//------------------------------------------------------------------------------------
// Details: Returns the final version of the MI result record built up in the
// command's
//          Acknowledge function. The one line text of MI result.
// Type:    Overridden.
// Args:    None.
// Return:  CMIUtilString & - MI text version of the MI result record.
// Throws:  None.
//--
const CMIUtilString &CMICmdBase::GetMIResultRecord() const {
  return m_miResultRecord.GetString();
}

//++
//------------------------------------------------------------------------------------
// Details: Retrieve from the command additional MI result to its 1 line
// response.
//          Because of using LLDB additional 'fake'/hack output is sometimes
//          required to
//          help the driver client operate i.e. Eclipse.
// Type:    Overridden.
// Args:    None.
// Return:  CMIUtilString & - MI text version of the MI result record.
// Throws:  None.
//--
const CMIUtilString &CMICmdBase::GetMIResultRecordExtra() const {
  return m_miResultRecordExtra;
}

//++
//------------------------------------------------------------------------------------
// Details: Hss *this command got additional MI result to its 1 line response.
//          Because of using LLDB additional 'fake'/hack output is sometimes
//          required to
//          help the driver client operate i.e. Eclipse.
// Type:    Overridden.
// Args:    None.
// Return:  bool    - True = Yes have additional MI output, false = no nothing
// extra.
// Throws:  None.
//--
bool CMICmdBase::HasMIResultRecordExtra() const {
  return m_bHasResultRecordExtra;
}

//++
//------------------------------------------------------------------------------------
// Details: Short cut function to enter error information into the command's
// metadata
//          object and set the command's error status.
// Type:    Method.
// Args:    rErrMsg - (R) Status description.
// Return:  None.
// Throws:  None.
//--
void CMICmdBase::SetError(const CMIUtilString &rErrMsg) {
  m_cmdData.bCmdValid = false;
  m_cmdData.strErrorDescription = rErrMsg;
  m_cmdData.bCmdExecutedSuccessfully = false;

  const CMICmnMIValueResult valueResult("msg", CMICmnMIValueConst(rErrMsg));
  const CMICmnMIResultRecord miResultRecord(
      m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
      valueResult);
  m_miResultRecord = miResultRecord;
  m_cmdData.strMiCmdResultRecord = miResultRecord.GetString();
}

//++
//------------------------------------------------------------------------------------
// Details: Short cut function to check MI command's execute status and
//          set an error in case of failure.
// Type:    Method.
// Args:    error - (R) Error description object.
//          successHandler - (R) function describing actions to execute
//          in case of success state of passed SBError object.
//          errorHandler - (R) function describing actions to execute
//          in case of fail status of passed SBError object.
// Return:  bool.
// Throws:  None.
//--
bool CMICmdBase::HandleSBError(const lldb::SBError &error,
                               const std::function<bool()> &successHandler,
                               const std::function<void()> &errorHandler) {
  if (error.Success())
    return successHandler();

  SetError(error.GetCString());
  errorHandler();
  return MIstatus::failure;
}

//++
//------------------------------------------------------------------------------------
// Details: Short cut function to check MI command's execute status and
//          call specified handler function for success case.
// Type:    Method.
// Args:    error - (R) Error description object.
//          successHandler - (R) function describing actions to execute
//          in case of success state of passed SBError object.
// Return:  bool.
// Throws:  None.
//--
bool CMICmdBase::HandleSBErrorWithSuccess(
    const lldb::SBError &error,
    const std::function<bool()> &successHandler) {
  return HandleSBError(error, successHandler);
}

//++
//------------------------------------------------------------------------------------
// Details: Short cut function to check MI command's execute status and
//          call specified handler function for error case.
// Type:    Method.
// Args:    error - (R) Error description object.
//          errorHandler - (R) function describing actions to execute
//          in case of fail status of passed SBError object.
// Return:  bool.
// Throws:  None.
//--
bool CMICmdBase::HandleSBErrorWithFailure(
    const lldb::SBError &error,
    const std::function<void()> &errorHandler) {
  return HandleSBError(error, [] { return MIstatus::success; }, errorHandler);
}

//++
//------------------------------------------------------------------------------------
// Details: Ask a command to provide its unique identifier.
// Type:    Method.
// Args:    A unique identifier for this command class.
// Return:  None.
// Throws:  None.
//--
MIuint CMICmdBase::GetGUID() {
  MIuint64 vptr = reinterpret_cast<MIuint64>(this);
  MIuint id = (vptr)&0xFFFFFFFF;
  id ^= (vptr >> 32) & 0xFFFFFFFF;

  return id;
}

//++
//------------------------------------------------------------------------------------
// Details: The invoker requires this function. The parses the command line
// options
//          arguments to extract values for each of those arguments.
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdBase::ParseArgs() {
  // Do nothing - override to implement

  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: Having previously given CMICmdArgSet m_setCmdArgs all the argument
// or option
//          definitions for the command to handle proceed to parse and validate
//          the
//          command's options text for those arguments and extract the values
//          for each if
//          any.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdBase::ParseValidateCmdOptions() {
  CMICmdArgContext argCntxt(m_cmdData.strMiCmdOption);
  if (m_setCmdArgs.Validate(m_cmdData.strMiCmd, argCntxt))
    return MIstatus::success;

  SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_ARGS),
                                 m_cmdData.strMiCmd.c_str(),
                                 m_setCmdArgs.GetErrorDescription().c_str()));

  return MIstatus::failure;
}

//++
//------------------------------------------------------------------------------------
// Details: If the MI Driver is not operating via a client i.e. Eclipse but say
// operating
//          on a executable passed in as a argument to the drive then what
//          should the driver
//          do on a command failing? Either continue operating or exit the
//          application.
//          Override this function where a command failure cannot allow the
//          driver to
//          continue operating.
// Type:    Overrideable.
// Args:    None.
// Return:  bool - True = Fatal if command fails, false = can continue if
// command fails.
// Throws:  None.
//--
bool CMICmdBase::GetExitAppOnCommandFailure() const { return false; }
