//===-- MICmdCmdBreak.cpp ---------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// Overview:    CMICmdCmdBreakInsert            implementation.
//              CMICmdCmdBreakDelete            implementation.
//              CMICmdCmdBreakDisable           implementation.
//              CMICmdCmdBreakEnable            implementation.
//              CMICmdCmdBreakAfter             implementation.
//              CMICmdCmdBreakCondition         implementation.

// Third Party Headers:
#include "lldb/API/SBBreakpointLocation.h"

// In-house headers:
#include "MICmdArgValFile.h"
#include "MICmdArgValListOfN.h"
#include "MICmdArgValNumber.h"
#include "MICmdArgValOptionLong.h"
#include "MICmdArgValOptionShort.h"
#include "MICmdArgValString.h"
#include "MICmdArgValThreadGrp.h"
#include "MICmdCmdBreak.h"
#include "MICmnLLDBDebugSessionInfo.h"
#include "MICmnLLDBDebugger.h"
#include "MICmnMIOutOfBandRecord.h"
#include "MICmnMIResultRecord.h"
#include "MICmnMIValueConst.h"
#include "MICmnStreamStdout.h"

//++
//------------------------------------------------------------------------------------
// Details: CMICmdCmdBreakInsert constructor.
// Type:    Method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmdCmdBreakInsert::CMICmdCmdBreakInsert()
    : m_bBrkPtIsTemp(false), m_bBrkPtIsPending(false), m_nBrkPtIgnoreCount(0),
      m_bBrkPtEnabled(false), m_bBrkPtCondition(false), m_bBrkPtThreadId(false),
      m_nBrkPtThreadId(0), m_constStrArgNamedTempBrkPt("t"),
      m_constStrArgNamedHWBrkPt("h"), m_constStrArgNamedPendinfBrkPt("f"),
      m_constStrArgNamedDisableBrkPt("d"), m_constStrArgNamedTracePt("a"),
      m_constStrArgNamedConditionalBrkPt("c"), m_constStrArgNamedInoreCnt("i"),
      m_constStrArgNamedRestrictBrkPtToThreadId("p"),
      m_constStrArgNamedLocation("location") {
  // Command factory matches this name with that received from the stdin stream
  m_strMiCmd = "break-insert";

  // Required by the CMICmdFactory when registering *this command
  m_pSelfCreatorFn = &CMICmdCmdBreakInsert::CreateSelf;
}

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

//++
//------------------------------------------------------------------------------------
// 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 CMICmdCmdBreakInsert::ParseArgs() {
  m_setCmdArgs.Add(
      new CMICmdArgValOptionShort(m_constStrArgNamedTempBrkPt, false, true));
  // Not implemented m_setCmdArgs.Add(new CMICmdArgValOptionShort(
  // m_constStrArgNamedHWBrkPt, false, false));
  m_setCmdArgs.Add(new CMICmdArgValOptionShort(
      m_constStrArgNamedPendinfBrkPt, false, true,
      CMICmdArgValListBase::eArgValType_StringQuotedNumberPath, 1));
  m_setCmdArgs.Add(new CMICmdArgValOptionShort(m_constStrArgNamedDisableBrkPt,
                                               false, false));
  // Not implemented m_setCmdArgs.Add(new CMICmdArgValOptionShort(
  // m_constStrArgNamedTracePt, false, false));
  m_setCmdArgs.Add(new CMICmdArgValOptionShort(
      m_constStrArgNamedConditionalBrkPt, false, true,
      CMICmdArgValListBase::eArgValType_StringQuoted, 1));
  m_setCmdArgs.Add(
      new CMICmdArgValOptionShort(m_constStrArgNamedInoreCnt, false, true,
                                  CMICmdArgValListBase::eArgValType_Number, 1));
  m_setCmdArgs.Add(new CMICmdArgValOptionShort(
      m_constStrArgNamedRestrictBrkPtToThreadId, false, true,
      CMICmdArgValListBase::eArgValType_Number, 1));
  m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgNamedLocation, false,
                                          true, false, false, true));
  return ParseValidateCmdOptions();
}

//++
//------------------------------------------------------------------------------------
// Helper function for CMICmdCmdBreakInsert::Execute().
//
// Given a string, return the position of the ':' separator in 'file:func'
// or 'file:line', if any.  If not found, return npos.  For example, return
// 5 for 'foo.c:std::string'.
//--
static size_t findFileSeparatorPos(const std::string &x) {
  // Full paths in windows can have ':' after a drive letter, so we
  // search backwards, taking care to skip C++ namespace tokens '::'.
  size_t n = x.rfind(':');
  while (n != std::string::npos && n > 1 && x[n - 1] == ':') {
    n = x.rfind(':', n - 2);
  }
  return n;
}

//++
//------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command does work in this
// function.
//          The command is likely to communicate with the LLDB SBDebugger in
//          here.
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdCmdBreakInsert::Execute() {
  CMICMDBASE_GETOPTION(pArgTempBrkPt, OptionShort, m_constStrArgNamedTempBrkPt);
  CMICMDBASE_GETOPTION(pArgThreadGroup, OptionLong, m_constStrArgThreadGroup);
  CMICMDBASE_GETOPTION(pArgLocation, String, m_constStrArgNamedLocation);
  CMICMDBASE_GETOPTION(pArgIgnoreCnt, OptionShort, m_constStrArgNamedInoreCnt);
  CMICMDBASE_GETOPTION(pArgPendingBrkPt, OptionShort,
                       m_constStrArgNamedPendinfBrkPt);
  CMICMDBASE_GETOPTION(pArgDisableBrkPt, OptionShort,
                       m_constStrArgNamedDisableBrkPt);
  CMICMDBASE_GETOPTION(pArgConditionalBrkPt, OptionShort,
                       m_constStrArgNamedConditionalBrkPt);
  CMICMDBASE_GETOPTION(pArgRestrictBrkPtToThreadId, OptionShort,
                       m_constStrArgNamedRestrictBrkPtToThreadId);

  // Ask LLDB for the target to check if we have valid or dummy one.
  CMICmnLLDBDebugSessionInfo &rSessionInfo(
      CMICmnLLDBDebugSessionInfo::Instance());
  lldb::SBTarget sbTarget = rSessionInfo.GetTarget();

  m_bBrkPtEnabled = !pArgDisableBrkPt->GetFound();
  m_bBrkPtIsTemp = pArgTempBrkPt->GetFound();
  m_bHaveArgOptionThreadGrp = pArgThreadGroup->GetFound();
  if (m_bHaveArgOptionThreadGrp) {
    MIuint nThreadGrp = 0;
    pArgThreadGroup->GetExpectedOption<CMICmdArgValThreadGrp, MIuint>(
        nThreadGrp);
    m_strArgOptionThreadGrp = CMIUtilString::Format("i%d", nThreadGrp);
  }

  if (sbTarget == rSessionInfo.GetDebugger().GetDummyTarget())
    m_bBrkPtIsPending = true;
  else
    m_bBrkPtIsPending = pArgPendingBrkPt->GetFound();

  if (pArgLocation->GetFound())
    m_brkName = pArgLocation->GetValue();
  else if (m_bBrkPtIsPending) {
    pArgPendingBrkPt->GetExpectedOption<CMICmdArgValString, CMIUtilString>(
        m_brkName);
  }
  if (pArgIgnoreCnt->GetFound()) {
    pArgIgnoreCnt->GetExpectedOption<CMICmdArgValNumber, MIuint>(
        m_nBrkPtIgnoreCount);
  }
  m_bBrkPtCondition = pArgConditionalBrkPt->GetFound();
  if (m_bBrkPtCondition) {
    pArgConditionalBrkPt->GetExpectedOption<CMICmdArgValString, CMIUtilString>(
        m_brkPtCondition);
  }
  m_bBrkPtThreadId = pArgRestrictBrkPtToThreadId->GetFound();
  if (m_bBrkPtCondition) {
    pArgRestrictBrkPtToThreadId->GetExpectedOption<CMICmdArgValNumber, MIuint>(
        m_nBrkPtThreadId);
  }

  // Determine if break on a file line or at a function
  BreakPoint_e eBrkPtType = eBreakPoint_NotDefineYet;
  CMIUtilString fileName;
  MIuint nFileLine = 0;
  CMIUtilString strFileFn;
  CMIUtilString rStrLineOrFn;
  // Is the string in the form 'file:func' or 'file:line'?
  // If so, find the position of the ':' separator.
  const size_t nPosColon = findFileSeparatorPos(m_brkName);
  if (nPosColon != std::string::npos) {
    // Extract file name and line number from it
    fileName = m_brkName.substr(0, nPosColon);
    rStrLineOrFn =
        m_brkName.substr(nPosColon + 1, m_brkName.size() - nPosColon - 1);

    if (rStrLineOrFn.empty())
      eBrkPtType = eBreakPoint_ByName;
    else {
      MIint64 nValue = 0;
      if (rStrLineOrFn.ExtractNumber(nValue)) {
        nFileLine = static_cast<MIuint>(nValue);
        eBrkPtType = eBreakPoint_ByFileLine;
      } else {
        strFileFn = rStrLineOrFn;
        eBrkPtType = eBreakPoint_ByFileFn;
      }
    }
  }

  // Determine if break defined as an address
  lldb::addr_t nAddress = 0;
  if (eBrkPtType == eBreakPoint_NotDefineYet) {
    MIint64 nValue = 0;
    if (m_brkName.ExtractNumber(nValue)) {
      nAddress = static_cast<lldb::addr_t>(nValue);
      eBrkPtType = eBreakPoint_ByAddress;
    }
  }

  // Break defined as an function
  if (eBrkPtType == eBreakPoint_NotDefineYet) {
    eBrkPtType = eBreakPoint_ByName;
  }

  // Ask LLDB to create a breakpoint
  bool bOk = MIstatus::success;
  switch (eBrkPtType) {
  case eBreakPoint_ByAddress:
    m_brkPt = sbTarget.BreakpointCreateByAddress(nAddress);
    break;
  case eBreakPoint_ByFileFn: {
    lldb::SBFileSpecList module; // search in all modules
    lldb::SBFileSpecList compUnit;
    compUnit.Append(lldb::SBFileSpec(fileName.c_str()));
    m_brkPt =
        sbTarget.BreakpointCreateByName(strFileFn.c_str(), module, compUnit);
    break;
  }
  case eBreakPoint_ByFileLine:
    m_brkPt = sbTarget.BreakpointCreateByLocation(fileName.c_str(), nFileLine);
    break;
  case eBreakPoint_ByName:
    m_brkPt = sbTarget.BreakpointCreateByName(m_brkName.c_str(), nullptr);
    break;
  case eBreakPoint_count:
  case eBreakPoint_NotDefineYet:
  case eBreakPoint_Invalid:
    bOk = MIstatus::failure;
    break;
  }

  if (bOk) {
    if (!m_bBrkPtIsPending && (m_brkPt.GetNumLocations() == 0)) {
      sbTarget.BreakpointDelete(m_brkPt.GetID());
      SetError(
          CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_LOCATION_NOT_FOUND),
                                m_cmdData.strMiCmd.c_str(), m_brkName.c_str()));
      return MIstatus::failure;
    }

    m_brkPt.SetEnabled(m_bBrkPtEnabled);
    m_brkPt.SetIgnoreCount(m_nBrkPtIgnoreCount);
    if (m_bBrkPtCondition)
      m_brkPt.SetCondition(m_brkPtCondition.c_str());
    if (m_bBrkPtThreadId)
      m_brkPt.SetThreadID(m_nBrkPtThreadId);
  }

  // CODETAG_LLDB_BREAKPOINT_CREATION
  // This is in the main thread
  // Record break point information to be by LLDB event handler function
  CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
  if (!rSessionInfo.GetBrkPtInfo(m_brkPt, sBrkPtInfo))
    return MIstatus::failure;
  sBrkPtInfo.m_id = m_brkPt.GetID();
  sBrkPtInfo.m_bDisp = m_bBrkPtIsTemp;
  sBrkPtInfo.m_bEnabled = m_bBrkPtEnabled;
  sBrkPtInfo.m_bHaveArgOptionThreadGrp = m_bHaveArgOptionThreadGrp;
  sBrkPtInfo.m_strOptThrdGrp = m_strArgOptionThreadGrp;
  sBrkPtInfo.m_nTimes = m_brkPt.GetHitCount();
  sBrkPtInfo.m_strOrigLoc = m_brkName;
  sBrkPtInfo.m_nIgnore = m_nBrkPtIgnoreCount;
  sBrkPtInfo.m_bPending = m_bBrkPtIsPending;
  sBrkPtInfo.m_bCondition = m_bBrkPtCondition;
  sBrkPtInfo.m_strCondition = m_brkPtCondition;
  sBrkPtInfo.m_bBrkPtThreadId = m_bBrkPtThreadId;
  sBrkPtInfo.m_nBrkPtThreadId = m_nBrkPtThreadId;

  bOk = bOk && rSessionInfo.RecordBrkPtInfo(m_brkPt.GetID(), sBrkPtInfo);
  if (!bOk) {
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID),
                                   m_cmdData.strMiCmd.c_str(),
                                   m_brkName.c_str()));
    return MIstatus::failure;
  }

  // CODETAG_LLDB_BRKPT_ID_MAX
  if (m_brkPt.GetID() > (lldb::break_id_t)rSessionInfo.m_nBrkPointCntMax) {
    SetError(CMIUtilString::Format(
        MIRSRC(IDS_CMD_ERR_BRKPT_CNT_EXCEEDED), m_cmdData.strMiCmd.c_str(),
        rSessionInfo.m_nBrkPointCntMax, m_brkName.c_str()));
    return MIstatus::failure;
  }

  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command prepares a MI Record
// Result
//          for the work carried out in the Execute().
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdCmdBreakInsert::Acknowledge() {
  // Get breakpoint information
  CMICmnLLDBDebugSessionInfo &rSessionInfo(
      CMICmnLLDBDebugSessionInfo::Instance());
  CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
  if (!rSessionInfo.RecordBrkPtInfoGet(m_brkPt.GetID(), sBrkPtInfo))
    return MIstatus::failure;

  // MI print
  // "^done,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016"
  // PRIx64
  // "\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",thread-groups=[\"%s\"],times=\"%d\",original-location=\"%s\"}"
  CMICmnMIValueTuple miValueTuple;
  if (!rSessionInfo.MIResponseFormBrkPtInfo(sBrkPtInfo, miValueTuple))
    return MIstatus::failure;

  const CMICmnMIValueResult miValueResultD("bkpt", miValueTuple);
  const CMICmnMIResultRecord miRecordResult(
      m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
      miValueResultD);
  m_miResultRecord = miRecordResult;

  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this command. The
// factory
//          calls this function to create an instance of *this command.
// Type:    Static method.
// Args:    None.
// Return:  CMICmdBase * - Pointer to a new command.
// Throws:  None.
//--
CMICmdBase *CMICmdCmdBreakInsert::CreateSelf() {
  return new CMICmdCmdBreakInsert();
}

//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------

//++
//------------------------------------------------------------------------------------
// Details: CMICmdCmdBreakDelete constructor.
// Type:    Method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmdCmdBreakDelete::CMICmdCmdBreakDelete()
    : m_constStrArgNamedBrkPt("breakpoint") {
  // Command factory matches this name with that received from the stdin stream
  m_strMiCmd = "break-delete";

  // Required by the CMICmdFactory when registering *this command
  m_pSelfCreatorFn = &CMICmdCmdBreakDelete::CreateSelf;
}

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

//++
//------------------------------------------------------------------------------------
// 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 CMICmdCmdBreakDelete::ParseArgs() {
  m_setCmdArgs.Add(
      new CMICmdArgValListOfN(m_constStrArgNamedBrkPt, true, true,
                              CMICmdArgValListBase::eArgValType_Number));
  return ParseValidateCmdOptions();
}

//++
//------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command does work in this
// function.
//          The command is likely to communicate with the LLDB SBDebugger in
//          here.
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdCmdBreakDelete::Execute() {
  CMICMDBASE_GETOPTION(pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt);

  // ATM we only handle one break point ID
  MIuint64 nBrk = UINT64_MAX;
  if (!pArgBrkPt->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nBrk)) {
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID),
                                   m_cmdData.strMiCmd.c_str(),
                                   m_constStrArgNamedBrkPt.c_str()));
    return MIstatus::failure;
  }

  CMICmnLLDBDebugSessionInfo &rSessionInfo(
      CMICmnLLDBDebugSessionInfo::Instance());
  const bool bBrkPt = rSessionInfo.GetTarget().BreakpointDelete(
      static_cast<lldb::break_id_t>(nBrk));
  if (!bBrkPt) {
    const CMIUtilString strBrkNum(CMIUtilString::Format("%d", nBrk));
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID),
                                   m_cmdData.strMiCmd.c_str(),
                                   strBrkNum.c_str()));
    return MIstatus::failure;
  }

  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command prepares a MI Record
// Result
//          for the work carried out in the Execute().
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdCmdBreakDelete::Acknowledge() {
  const CMICmnMIResultRecord miRecordResult(
      m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
  m_miResultRecord = miRecordResult;

  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this command. The
// factory
//          calls this function to create an instance of *this command.
// Type:    Static method.
// Args:    None.
// Return:  CMICmdBase * - Pointer to a new command.
// Throws:  None.
//--
CMICmdBase *CMICmdCmdBreakDelete::CreateSelf() {
  return new CMICmdCmdBreakDelete();
}

//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------

//++
//------------------------------------------------------------------------------------
// Details: CMICmdCmdBreakDisable constructor.
// Type:    Method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmdCmdBreakDisable::CMICmdCmdBreakDisable()
    : m_constStrArgNamedBrkPt("breakpoint"), m_bBrkPtDisabledOk(false),
      m_nBrkPtId(0) {
  // Command factory matches this name with that received from the stdin stream
  m_strMiCmd = "break-disable";

  // Required by the CMICmdFactory when registering *this command
  m_pSelfCreatorFn = &CMICmdCmdBreakDisable::CreateSelf;
}

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

//++
//------------------------------------------------------------------------------------
// 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 CMICmdCmdBreakDisable::ParseArgs() {
  m_setCmdArgs.Add(
      new CMICmdArgValListOfN(m_constStrArgNamedBrkPt, true, true,
                              CMICmdArgValListBase::eArgValType_Number));
  return ParseValidateCmdOptions();
}

//++
//------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command does work in this
// function.
//          The command is likely to communicate with the LLDB SBDebugger in
//          here.
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdCmdBreakDisable::Execute() {
  CMICMDBASE_GETOPTION(pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt);

  // ATM we only handle one break point ID
  MIuint64 nBrk = UINT64_MAX;
  if (!pArgBrkPt->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nBrk)) {
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID),
                                   m_cmdData.strMiCmd.c_str(),
                                   m_constStrArgNamedBrkPt.c_str()));
    return MIstatus::failure;
  }

  CMICmnLLDBDebugSessionInfo &rSessionInfo(
      CMICmnLLDBDebugSessionInfo::Instance());
  lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(
      static_cast<lldb::break_id_t>(nBrk));
  if (brkPt.IsValid()) {
    m_bBrkPtDisabledOk = true;
    brkPt.SetEnabled(false);
    m_nBrkPtId = nBrk;
  }

  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command prepares a MI Record
// Result
//          for the work carried out in the Execute().
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdCmdBreakDisable::Acknowledge() {
  if (m_bBrkPtDisabledOk) {
    const CMICmnMIResultRecord miRecordResult(
        m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
    m_miResultRecord = miRecordResult;
    return MIstatus::success;
  }

  const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId));
  const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
      MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), strBrkPtId.c_str()));
  const CMICmnMIValueResult miValueResult("msg", miValueConst);
  const CMICmnMIResultRecord miRecordResult(
      m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
      miValueResult);
  m_miResultRecord = miRecordResult;

  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this command. The
// factory
//          calls this function to create an instance of *this command.
// Type:    Static method.
// Args:    None.
// Return:  CMICmdBase * - Pointer to a new command.
// Throws:  None.
//--
CMICmdBase *CMICmdCmdBreakDisable::CreateSelf() {
  return new CMICmdCmdBreakDisable();
}

//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------

//++
//------------------------------------------------------------------------------------
// Details: CMICmdCmdBreakEnable constructor.
// Type:    Method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmdCmdBreakEnable::CMICmdCmdBreakEnable()
    : m_constStrArgNamedBrkPt("breakpoint"), m_bBrkPtEnabledOk(false),
      m_nBrkPtId(0) {
  // Command factory matches this name with that received from the stdin stream
  m_strMiCmd = "break-enable";

  // Required by the CMICmdFactory when registering *this command
  m_pSelfCreatorFn = &CMICmdCmdBreakEnable::CreateSelf;
}

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

//++
//------------------------------------------------------------------------------------
// 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 CMICmdCmdBreakEnable::ParseArgs() {
  m_setCmdArgs.Add(
      new CMICmdArgValListOfN(m_constStrArgNamedBrkPt, true, true,
                              CMICmdArgValListBase::eArgValType_Number));
  return ParseValidateCmdOptions();
}

//++
//------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command does work in this
// function.
//          The command is likely to communicate with the LLDB SBDebugger in
//          here.
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdCmdBreakEnable::Execute() {
  CMICMDBASE_GETOPTION(pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt);

  // ATM we only handle one break point ID
  MIuint64 nBrk = UINT64_MAX;
  if (!pArgBrkPt->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nBrk)) {
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID),
                                   m_cmdData.strMiCmd.c_str(),
                                   m_constStrArgNamedBrkPt.c_str()));
    return MIstatus::failure;
  }

  CMICmnLLDBDebugSessionInfo &rSessionInfo(
      CMICmnLLDBDebugSessionInfo::Instance());
  lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(
      static_cast<lldb::break_id_t>(nBrk));
  if (brkPt.IsValid()) {
    m_bBrkPtEnabledOk = true;
    brkPt.SetEnabled(true);
    m_nBrkPtId = nBrk;
  }

  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command prepares a MI Record
// Result
//          for the work carried out in the Execute().
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdCmdBreakEnable::Acknowledge() {
  if (m_bBrkPtEnabledOk) {
    const CMICmnMIResultRecord miRecordResult(
        m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
    m_miResultRecord = miRecordResult;
    return MIstatus::success;
  }

  const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId));
  const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
      MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), strBrkPtId.c_str()));
  const CMICmnMIValueResult miValueResult("msg", miValueConst);
  const CMICmnMIResultRecord miRecordResult(
      m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
      miValueResult);
  m_miResultRecord = miRecordResult;

  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this command. The
// factory
//          calls this function to create an instance of *this command.
// Type:    Static method.
// Args:    None.
// Return:  CMICmdBase * - Pointer to a new command.
// Throws:  None.
//--
CMICmdBase *CMICmdCmdBreakEnable::CreateSelf() {
  return new CMICmdCmdBreakEnable();
}

//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------

//++
//------------------------------------------------------------------------------------
// Details: CMICmdCmdBreakAfter constructor.
// Type:    Method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmdCmdBreakAfter::CMICmdCmdBreakAfter()
    : m_constStrArgNamedNumber("number"), m_constStrArgNamedCount("count"),
      m_nBrkPtId(0), m_nBrkPtCount(0) {
  // Command factory matches this name with that received from the stdin stream
  m_strMiCmd = "break-after";

  // Required by the CMICmdFactory when registering *this command
  m_pSelfCreatorFn = &CMICmdCmdBreakAfter::CreateSelf;
}

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

//++
//------------------------------------------------------------------------------------
// 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 CMICmdCmdBreakAfter::ParseArgs() {
  m_setCmdArgs.Add(
      new CMICmdArgValNumber(m_constStrArgNamedNumber, true, true));
  m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNamedCount, true, true));
  return ParseValidateCmdOptions();
}

//++
//------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command does work in this
// function.
//          The command is likely to communicate with the LLDB SBDebugger in
//          here.
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdCmdBreakAfter::Execute() {
  CMICMDBASE_GETOPTION(pArgNumber, Number, m_constStrArgNamedNumber);
  CMICMDBASE_GETOPTION(pArgCount, Number, m_constStrArgNamedCount);

  m_nBrkPtId = pArgNumber->GetValue();
  m_nBrkPtCount = pArgCount->GetValue();

  CMICmnLLDBDebugSessionInfo &rSessionInfo(
      CMICmnLLDBDebugSessionInfo::Instance());
  lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(
      static_cast<lldb::break_id_t>(m_nBrkPtId));
  if (brkPt.IsValid()) {
    brkPt.SetIgnoreCount(m_nBrkPtCount);

    CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
    if (!rSessionInfo.RecordBrkPtInfoGet(m_nBrkPtId, sBrkPtInfo)) {
      SetError(
          CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND),
                                m_cmdData.strMiCmd.c_str(), m_nBrkPtId));
      return MIstatus::failure;
    }
    sBrkPtInfo.m_nIgnore = m_nBrkPtCount;
    rSessionInfo.RecordBrkPtInfo(m_nBrkPtId, sBrkPtInfo);
  } else {
    const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId));
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID),
                                   m_cmdData.strMiCmd.c_str(),
                                   strBrkPtId.c_str()));
    return MIstatus::failure;
  }

  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command prepares a MI Record
// Result
//          for the work carried out in the Execute().
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdCmdBreakAfter::Acknowledge() {
  const CMICmnMIResultRecord miRecordResult(
      m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
  m_miResultRecord = miRecordResult;

  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this command. The
// factory
//          calls this function to create an instance of *this command.
// Type:    Static method.
// Args:    None.
// Return:  CMICmdBase * - Pointer to a new command.
// Throws:  None.
//--
CMICmdBase *CMICmdCmdBreakAfter::CreateSelf() {
  return new CMICmdCmdBreakAfter();
}

//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------

//++
//------------------------------------------------------------------------------------
// Details: CMICmdCmdBreakCondition constructor.
// Type:    Method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmdCmdBreakCondition::CMICmdCmdBreakCondition()
    : m_constStrArgNamedNumber("number"), m_constStrArgNamedExpr("expr"),
      m_constStrArgNamedExprNoQuotes(
          "expression not surround by quotes") // Not specified in MI spec, we
                                               // need to handle expressions not
                                               // surrounded by quotes
      ,
      m_nBrkPtId(0) {
  // Command factory matches this name with that received from the stdin stream
  m_strMiCmd = "break-condition";

  // Required by the CMICmdFactory when registering *this command
  m_pSelfCreatorFn = &CMICmdCmdBreakCondition::CreateSelf;
}

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

//++
//------------------------------------------------------------------------------------
// 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 CMICmdCmdBreakCondition::ParseArgs() {
  m_setCmdArgs.Add(
      new CMICmdArgValNumber(m_constStrArgNamedNumber, true, true));
  m_setCmdArgs.Add(
      new CMICmdArgValString(m_constStrArgNamedExpr, true, true, true, true));
  m_setCmdArgs.Add(new CMICmdArgValListOfN(
      m_constStrArgNamedExprNoQuotes, false, false,
      CMICmdArgValListBase::eArgValType_StringQuotedNumber));
  return ParseValidateCmdOptions();
}

//++
//------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command does work in this
// function.
//          The command is likely to communicate with the LLDB SBDebugger in
//          here.
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdCmdBreakCondition::Execute() {
  CMICMDBASE_GETOPTION(pArgNumber, Number, m_constStrArgNamedNumber);
  CMICMDBASE_GETOPTION(pArgExpr, String, m_constStrArgNamedExpr);

  m_nBrkPtId = pArgNumber->GetValue();
  m_strBrkPtExpr = pArgExpr->GetValue();
  m_strBrkPtExpr += GetRestOfExpressionNotSurroundedInQuotes();

  CMICmnLLDBDebugSessionInfo &rSessionInfo(
      CMICmnLLDBDebugSessionInfo::Instance());
  lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(
      static_cast<lldb::break_id_t>(m_nBrkPtId));
  if (brkPt.IsValid()) {
    brkPt.SetCondition(m_strBrkPtExpr.c_str());

    CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
    if (!rSessionInfo.RecordBrkPtInfoGet(m_nBrkPtId, sBrkPtInfo)) {
      SetError(
          CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND),
                                m_cmdData.strMiCmd.c_str(), m_nBrkPtId));
      return MIstatus::failure;
    }
    sBrkPtInfo.m_strCondition = m_strBrkPtExpr;
    rSessionInfo.RecordBrkPtInfo(m_nBrkPtId, sBrkPtInfo);
  } else {
    const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId));
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID),
                                   m_cmdData.strMiCmd.c_str(),
                                   strBrkPtId.c_str()));
    return MIstatus::failure;
  }

  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command prepares a MI Record
// Result
//          for the work carried out in the Execute().
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdCmdBreakCondition::Acknowledge() {
  const CMICmnMIResultRecord miRecordResult(
      m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
  m_miResultRecord = miRecordResult;

  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this command. The
// factory
//          calls this function to create an instance of *this command.
// Type:    Static method.
// Args:    None.
// Return:  CMICmdBase * - Pointer to a new command.
// Throws:  None.
//--
CMICmdBase *CMICmdCmdBreakCondition::CreateSelf() {
  return new CMICmdCmdBreakCondition();
}

//++
//------------------------------------------------------------------------------------
// Details: A breakpoint expression can be passed to *this command as:
//              a single string i.e. '2' -> ok.
//              a quoted string i.e. "a > 100" -> ok
//              a non quoted string i.e. 'a > 100' -> not ok
//          CMICmdArgValString only extracts the first space separated string,
//          the "a".
//          This function using the optional argument type CMICmdArgValListOfN
//          collects
//          the rest of the expression so that is may be added to the 'a' part
//          to form a
//          complete expression string i.e. "a > 100".
//          If the expression value was guaranteed to be surrounded by quotes
//          them this
//          function would not be necessary.
// Type:    Method.
// Args:    None.
// Return:  CMIUtilString - Rest of the breakpoint expression.
// Throws:  None.
//--
CMIUtilString
CMICmdCmdBreakCondition::GetRestOfExpressionNotSurroundedInQuotes() {
  CMIUtilString strExpression;

  CMICmdArgValListOfN *pArgExprNoQuotes =
      CMICmdBase::GetOption<CMICmdArgValListOfN>(
          m_constStrArgNamedExprNoQuotes);
  if (pArgExprNoQuotes != nullptr) {
    const CMICmdArgValListBase::VecArgObjPtr_t &rVecExprParts(
        pArgExprNoQuotes->GetExpectedOptions());
    if (!rVecExprParts.empty()) {
      CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it =
          rVecExprParts.begin();
      while (it != rVecExprParts.end()) {
        const CMICmdArgValString *pPartExpr =
            static_cast<CMICmdArgValString *>(*it);
        const CMIUtilString &rPartExpr = pPartExpr->GetValue();
        strExpression += " ";
        strExpression += rPartExpr;

        // Next
        ++it;
      }
      strExpression = strExpression.Trim();
    }
  }

  return strExpression;
}
