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

// Overview:    CMICmdCmdGdbShow implementation.

// Third party headers:
#include "lldb/API/SBCompileUnit.h"
#include "lldb/API/SBFrame.h"
#include "lldb/API/SBLanguageRuntime.h"
#include "lldb/API/SBStringList.h"
#include "lldb/API/SBThread.h"

// In-house headers:
#include "MICmdArgValListOfN.h"
#include "MICmdArgValOptionLong.h"
#include "MICmdArgValString.h"
#include "MICmdCmdGdbShow.h"
#include "MICmnLLDBDebugSessionInfo.h"
#include "MICmnMIResultRecord.h"
#include "MICmnMIValueConst.h"

// Instantiations:
const CMICmdCmdGdbShow::MapGdbOptionNameToFnGdbOptionPtr_t
    CMICmdCmdGdbShow::ms_mapGdbOptionNameToFnGdbOptionPtr = {
        {"target-async", &CMICmdCmdGdbShow::OptionFnTargetAsync},
        {"print", &CMICmdCmdGdbShow::OptionFnPrint},
        {"language", &CMICmdCmdGdbShow::OptionFnLanguage},
        {"disassembly-flavor", &CMICmdCmdGdbShow::OptionFnDisassemblyFlavor},
        {"fallback", &CMICmdCmdGdbShow::OptionFnFallback}};

//++
//------------------------------------------------------------------------------------
// Details: CMICmdCmdGdbShow constructor.
// Type:    Method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmdCmdGdbShow::CMICmdCmdGdbShow()
    : m_constStrArgNamedGdbOption("option"), m_bGdbOptionRecognised(true),
      m_bGdbOptionFnSuccessful(false), m_bGbbOptionFnHasError(false),
      m_strGdbOptionFnError(MIRSRC(IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS)) {
  // Command factory matches this name with that received from the stdin stream
  m_strMiCmd = "gdb-show";

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

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

//++
//------------------------------------------------------------------------------------
// 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 - Function succeeded.
//          MIstatus::failure - Function failed.
// Throws:  None.
//--
bool CMICmdCmdGdbShow::ParseArgs() {
  m_setCmdArgs.Add(new CMICmdArgValListOfN(
      m_constStrArgNamedGdbOption, true, true,
      CMICmdArgValListBase::eArgValType_StringAnything));
  return ParseValidateCmdOptions();
}

//++
//------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command is executed in this
// function.
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Function succeeded.
//          MIstatus::failure - Function failed.
// Throws:  None.
//--
bool CMICmdCmdGdbShow::Execute() {
  CMICMDBASE_GETOPTION(pArgGdbOption, ListOfN, m_constStrArgNamedGdbOption);
  const CMICmdArgValListBase::VecArgObjPtr_t &rVecWords(
      pArgGdbOption->GetExpectedOptions());

  // Get the gdb-show option to carry out. This option will be used as an action
  // which should be done. Further arguments will be used as parameters for it.
  CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecWords.begin();
  const CMICmdArgValString *pOption =
      static_cast<const CMICmdArgValString *>(*it);
  const CMIUtilString strOption(pOption->GetValue());
  ++it;

  // Retrieve the parameter(s) for the option
  CMIUtilString::VecString_t vecWords;
  while (it != rVecWords.end()) {
    const CMICmdArgValString *pWord =
        static_cast<const CMICmdArgValString *>(*it);
    vecWords.push_back(pWord->GetValue());

    // Next
    ++it;
  }

  FnGdbOptionPtr pPrintRequestFn = nullptr;
  if (!GetOptionFn(strOption, pPrintRequestFn)) {
    // For unimplemented option handlers, fallback to a generic handler
    // ToDo: Remove this when ALL options have been implemented
    if (!GetOptionFn("fallback", pPrintRequestFn)) {
      m_bGdbOptionRecognised = false;
      m_strGdbOptionName = "fallback"; // This would be the strOption name
      return MIstatus::success;
    }
  }

  m_bGdbOptionFnSuccessful = (this->*(pPrintRequestFn))(vecWords);
  if (!m_bGdbOptionFnSuccessful && !m_bGbbOptionFnHasError)
    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() method.
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Function succeeded.
//          MIstatus::failure - Function failed.
// Throws:  None.
//--
bool CMICmdCmdGdbShow::Acknowledge() {
  // Print error if option isn't recognized:
  // ^error,msg="The request '%s' was not recognized, not implemented"
  if (!m_bGdbOptionRecognised) {
    const CMICmnMIValueConst miValueConst(
        CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND),
                              m_strGdbOptionName.c_str()));
    const CMICmnMIValueResult miValueResult("msg", miValueConst);
    const CMICmnMIResultRecord miRecordResult(
        m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
        miValueResult);
    m_miResultRecord = miRecordResult;
    return MIstatus::success;
  }

  // ^done,value="%s"
  if (m_bGdbOptionFnSuccessful && !m_strValue.empty()) {
    const CMICmnMIValueConst miValueConst(m_strValue);
    const CMICmnMIValueResult miValueResult("value", miValueConst);
    const CMICmnMIResultRecord miRecordResult(
        m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
        miValueResult);
    m_miResultRecord = miRecordResult;
    return MIstatus::success;
  } else if (m_bGdbOptionFnSuccessful) {
    // Ignore empty value (for fallback)
    const CMICmnMIResultRecord miRecordResult(
        m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
    m_miResultRecord = miRecordResult;
    return MIstatus::success;
  }

  // Print error if request failed:
  // ^error,msg="The request '%s' failed.
  const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
      MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_FAILED), m_strGdbOptionFnError.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 *CMICmdCmdGdbShow::CreateSelf() { return new CMICmdCmdGdbShow(); }

//++
//------------------------------------------------------------------------------------
// Details: Retrieve the print function's pointer for the matching print
// request.
// Type:    Method.
// Args:    vrPrintFnName   - (R) The info requested.
//          vrwpFn          - (W) The print function's pointer of the function
//          to carry out
// Return:  bool    - True = Print request is implemented, false = not found.
// Throws:  None.
//--
bool CMICmdCmdGdbShow::GetOptionFn(const CMIUtilString &vrPrintFnName,
                                   FnGdbOptionPtr &vrwpFn) const {
  vrwpFn = nullptr;

  const MapGdbOptionNameToFnGdbOptionPtr_t::const_iterator it =
      ms_mapGdbOptionNameToFnGdbOptionPtr.find(vrPrintFnName);
  if (it != ms_mapGdbOptionNameToFnGdbOptionPtr.end()) {
    vrwpFn = (*it).second;
    return true;
  }

  return false;
}

//++
//------------------------------------------------------------------------------------
// Details: Carry out work to complete the GDB show option 'target-async' to
// prepare
//          and send back the requested information.
// Type:    Method.
// Args:    vrWords - (R) List of additional parameters used by this option.
// Return:  MIstatus::success - Function succeeded.
//          MIstatus::failure - Function failed.
// Throws:  None.
//--
bool CMICmdCmdGdbShow::OptionFnTargetAsync(
    const CMIUtilString::VecString_t &vrWords) {
  MIunused(vrWords);

  // Get async mode
  CMICmnLLDBDebugSessionInfo &rSessionInfo(
      CMICmnLLDBDebugSessionInfo::Instance());
  const bool bAsyncMode = rSessionInfo.GetDebugger().GetAsync();

  m_strValue = bAsyncMode ? "on" : "off";
  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: Carry out work to complete the GDB show option 'print' to prepare
// and send
//          back the requested information.
// Type:    Method.
// Args:    vrWords - (R) List of additional parameters used by this option.
// Return:  MIstatus::success - Function succeeded.
//          MIstatus::failure - Function failed.
// Throws:  None.
//--
bool CMICmdCmdGdbShow::OptionFnPrint(
    const CMIUtilString::VecString_t &vrWords) {
  const bool bAllArgs(vrWords.size() == 1);
  if (!bAllArgs) {
    m_bGbbOptionFnHasError = true;
    m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_PRINT_BAD_ARGS);
    return MIstatus::failure;
  }

  const CMIUtilString strOption(vrWords[0]);
  CMIUtilString strOptionKey;
  bool bOptionValueDefault = false;
  if (CMIUtilString::Compare(strOption, "char-array-as-string"))
    strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintCharArrayAsString;
  else if (CMIUtilString::Compare(strOption, "expand-aggregates"))
    strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintExpandAggregates;
  else if (CMIUtilString::Compare(strOption, "aggregate-field-names")) {
    strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintAggregateFieldNames;
    bOptionValueDefault = true;
  } else {
    m_bGbbOptionFnHasError = true;
    m_strGdbOptionFnError = CMIUtilString::Format(
        MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_PRINT_UNKNOWN_OPTION),
        strOption.c_str());
    return MIstatus::failure;
  }

  bool bOptionValue = false;
  bOptionValue = bOptionValueDefault
                     ? !m_rLLDBDebugSessionInfo.SharedDataRetrieve<bool>(
                           strOptionKey, bOptionValue) ||
                           bOptionValue
                     : m_rLLDBDebugSessionInfo.SharedDataRetrieve<bool>(
                           strOptionKey, bOptionValue) &&
                           bOptionValue;

  m_strValue = bOptionValue ? "on" : "off";
  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: Carry out work to complete the GDB show option 'language' to prepare
//          and send back the requested information.
// Type:    Method.
// Args:    vrWords - (R) List of additional parameters used by this option.
// Return:  MIstatus::success - Function succeeded.
//          MIstatus::failure - Function failed.
// Throws:  None.
//--
bool CMICmdCmdGdbShow::OptionFnLanguage(
    const CMIUtilString::VecString_t &vrWords) {
  MIunused(vrWords);

  // Get current language
  CMICmnLLDBDebugSessionInfo &rSessionInfo(
      CMICmnLLDBDebugSessionInfo::Instance());
  lldb::SBThread sbThread = rSessionInfo.GetProcess().GetSelectedThread();
  const lldb::SBFrame sbFrame = sbThread.GetSelectedFrame();
  lldb::SBCompileUnit sbCompileUnit = sbFrame.GetCompileUnit();
  const lldb::LanguageType eLanguageType = sbCompileUnit.GetLanguage();

  m_strValue = lldb::SBLanguageRuntime::GetNameForLanguageType(eLanguageType);
  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: Carry out work to complete the GDB show option 'disassembly-flavor' to prepare
//          and send back the requested information.
// Type:    Method.
// Args:    vrWords - (R) List of additional parameters used by this option.
// Return:  MIstatus::success - Function succeeded.
//          MIstatus::failure - Function failed.
// Throws:  None.
//--
bool CMICmdCmdGdbShow::OptionFnDisassemblyFlavor(const CMIUtilString::VecString_t &vrWords) {
  MIunused(vrWords);

  // Get current disassembly flavor
  lldb::SBDebugger &rDbgr = m_rLLDBDebugSessionInfo.GetDebugger();
  m_strValue = lldb::SBDebugger::GetInternalVariableValue("target.x86-disassembly-flavor",
                                                          rDbgr.GetInstanceName()).GetStringAtIndex(0);
  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: Carry out work to complete the GDB show option to prepare and send
// back the
//          requested information.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Function succeeded.
//          MIstatus::failure - Function failed.
// Throws:  None.
//--
bool CMICmdCmdGdbShow::OptionFnFallback(
    const CMIUtilString::VecString_t &vrWords) {
  MIunused(vrWords);

  // Do nothing - intentional. This is a fallback function to do nothing.
  // This allows the search for gdb-show options to always succeed when the
  // option is not
  // found (implemented).

  return MIstatus::success;
}
