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

// Overview:    CMICmdCmdTargetSelect           implementation.

// Third Party Headers:
#include "lldb/API/SBCommandInterpreter.h"
#include "lldb/API/SBCommandReturnObject.h"
#include "lldb/API/SBStream.h"

// In-house headers:
#include "MICmdArgValNumber.h"
#include "MICmdArgValOptionLong.h"
#include "MICmdArgValOptionShort.h"
#include "MICmdArgValString.h"
#include "MICmdCmdTarget.h"
#include "MICmnLLDBDebugSessionInfo.h"
#include "MICmnLLDBDebugger.h"
#include "MICmnMIOutOfBandRecord.h"
#include "MICmnMIResultRecord.h"
#include "MICmnMIValueConst.h"

//++
//------------------------------------------------------------------------------------
// Details: CMICmdCmdTargetSelect constructor.
// Type:    Method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmdCmdTargetSelect::CMICmdCmdTargetSelect()
    : m_constStrArgNamedType("type"),
      m_constStrArgNamedParameters("parameters") {
  // Command factory matches this name with that received from the stdin stream
  m_strMiCmd = "target-select";

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

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

//++
//------------------------------------------------------------------------------------
// 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 CMICmdCmdTargetSelect::ParseArgs() {
  m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgNamedType, true, true));
  m_setCmdArgs.Add(
      new CMICmdArgValString(m_constStrArgNamedParameters, 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.
//          Synopsis: -target-select type parameters ...
//          Ref:
//          http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Target-Manipulation.html#GDB_002fMI-Target-Manipulation
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdCmdTargetSelect::Execute() {
  CMICMDBASE_GETOPTION(pArgType, String, m_constStrArgNamedType);
  CMICMDBASE_GETOPTION(pArgParameters, String, m_constStrArgNamedParameters);

  CMICmnLLDBDebugSessionInfo &rSessionInfo(
      CMICmnLLDBDebugSessionInfo::Instance());

  // Check we have a valid target
  // Note: target created via 'file-exec-and-symbols' command
  if (!rSessionInfo.GetTarget().IsValid()) {
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT),
                                   m_cmdData.strMiCmd.c_str()));
    return MIstatus::failure;
  }

  // Verify that we are executing remotely
  const CMIUtilString &rRemoteType(pArgType->GetValue());
  if (rRemoteType != "remote") {
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_TYPE),
                                   m_cmdData.strMiCmd.c_str(),
                                   rRemoteType.c_str()));
    return MIstatus::failure;
  }

  // Create a URL pointing to the remote gdb stub
  const CMIUtilString strUrl =
      CMIUtilString::Format("connect://%s", pArgParameters->GetValue().c_str());

  // Ask LLDB to connect to the target port
  const char *pPlugin("gdb-remote");
  lldb::SBError error;
  lldb::SBProcess process = rSessionInfo.GetTarget().ConnectRemote(
      rSessionInfo.GetListener(), strUrl.c_str(), pPlugin, error);

  // Verify that we have managed to connect successfully
  lldb::SBStream errMsg;
  error.GetDescription(errMsg);
  if (!process.IsValid()) {
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_PLUGIN),
                                   m_cmdData.strMiCmd.c_str(),
                                   errMsg.GetData()));
    return MIstatus::failure;
  }
  if (error.Fail()) {
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_CONNECT_TO_TARGET),
                                   m_cmdData.strMiCmd.c_str(),
                                   errMsg.GetData()));
    return MIstatus::failure;
  }

  // Set the environment path if we were given one
  CMIUtilString strWkDir;
  if (rSessionInfo.SharedDataRetrieve<CMIUtilString>(
          rSessionInfo.m_constStrSharedDataKeyWkDir, strWkDir)) {
    lldb::SBDebugger &rDbgr = rSessionInfo.GetDebugger();
    if (!rDbgr.SetCurrentPlatformSDKRoot(strWkDir.c_str())) {
      SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_FNFAILED),
                                     m_cmdData.strMiCmd.c_str(),
                                     "target-select"));
      return MIstatus::failure;
    }
  }

  // Set the shared object path if we were given one
  CMIUtilString strSolibPath;
  if (rSessionInfo.SharedDataRetrieve<CMIUtilString>(
          rSessionInfo.m_constStrSharedDataSolibPath, strSolibPath)) {
    lldb::SBDebugger &rDbgr = rSessionInfo.GetDebugger();
    lldb::SBCommandInterpreter cmdIterpreter = rDbgr.GetCommandInterpreter();

    CMIUtilString strCmdString = CMIUtilString::Format(
        "target modules search-paths add . %s", strSolibPath.c_str());

    lldb::SBCommandReturnObject retObj;
    cmdIterpreter.HandleCommand(strCmdString.c_str(), retObj, false);

    if (!retObj.Succeeded()) {
      SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_FNFAILED),
                                     m_cmdData.strMiCmd.c_str(),
                                     "target-select"));
      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 CMICmdCmdTargetSelect::Acknowledge() {
  const CMICmnMIResultRecord miRecordResult(
      m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Connected);
  m_miResultRecord = miRecordResult;

  CMICmnLLDBDebugSessionInfo &rSessionInfo(
      CMICmnLLDBDebugSessionInfo::Instance());
  lldb::pid_t pid = rSessionInfo.GetProcess().GetProcessID();
  // Prod the client i.e. Eclipse with out-of-band results to help it 'continue'
  // because it is using LLDB debugger
  // Give the client '=thread-group-started,id="i1"'
  m_bHasResultRecordExtra = true;
  const CMICmnMIValueConst miValueConst2("i1");
  const CMICmnMIValueResult miValueResult2("id", miValueConst2);
  const CMIUtilString strPid(CMIUtilString::Format("%lld", pid));
  const CMICmnMIValueConst miValueConst(strPid);
  const CMICmnMIValueResult miValueResult("pid", miValueConst);
  CMICmnMIOutOfBandRecord miOutOfBand(
      CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupStarted, miValueResult2);
  miOutOfBand.Add(miValueResult);
  m_miResultRecordExtra = miOutOfBand.GetString();

  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 *CMICmdCmdTargetSelect::CreateSelf() {
  return new CMICmdCmdTargetSelect();
}

//++
//------------------------------------------------------------------------------------
// Details: CMICmdCmdTargetAttach constructor.
// Type:    Method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmdCmdTargetAttach::CMICmdCmdTargetAttach()
    : m_constStrArgPid("pid"), m_constStrArgNamedFile("n"),
      m_constStrArgWaitFor("waitfor") {
  // Command factory matches this name with that received from the stdin stream
  m_strMiCmd = "target-attach";

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

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

//++
//------------------------------------------------------------------------------------
// 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 CMICmdCmdTargetAttach::ParseArgs() {
  m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgPid, false, true));
  m_setCmdArgs.Add(
      new CMICmdArgValOptionShort(m_constStrArgNamedFile, false, true,
                                  CMICmdArgValListBase::eArgValType_String, 1));
  m_setCmdArgs.Add(
      new CMICmdArgValOptionLong(m_constStrArgWaitFor, false, 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.
//          Synopsis: -target-attach file
//          Ref:
//          http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Target-Manipulation.html#GDB_002fMI-Target-Manipulation
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdCmdTargetAttach::Execute() {
  CMICMDBASE_GETOPTION(pArgPid, Number, m_constStrArgPid);
  CMICMDBASE_GETOPTION(pArgFile, OptionShort, m_constStrArgNamedFile);
  CMICMDBASE_GETOPTION(pArgWaitFor, OptionLong, m_constStrArgWaitFor);

  CMICmnLLDBDebugSessionInfo &rSessionInfo(
      CMICmnLLDBDebugSessionInfo::Instance());

  // If the current target is invalid, create one
  lldb::SBTarget target = rSessionInfo.GetTarget();
  if (!target.IsValid()) {
    target = rSessionInfo.GetDebugger().CreateTarget(NULL);
    if (!target.IsValid()) {
      SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT),
                                     m_cmdData.strMiCmd.c_str()));
      return MIstatus::failure;
    }
  }

  lldb::SBError error;
  lldb::SBListener listener;
  if (pArgPid->GetFound() && pArgPid->GetValid()) {
    lldb::pid_t pid;
    pid = pArgPid->GetValue();
    target.AttachToProcessWithID(listener, pid, error);
  } else if (pArgFile->GetFound() && pArgFile->GetValid()) {
    bool bWaitFor = (pArgWaitFor->GetFound());
    CMIUtilString file;
    pArgFile->GetExpectedOption<CMICmdArgValString>(file);
    target.AttachToProcessWithName(listener, file.c_str(), bWaitFor, error);
  } else {
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_ATTACH_BAD_ARGS),
                                   m_cmdData.strMiCmd.c_str()));
    return MIstatus::failure;
  }

  lldb::SBStream errMsg;
  if (error.Fail()) {
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_ATTACH_FAILED),
                                   m_cmdData.strMiCmd.c_str(),
                                   errMsg.GetData()));
    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 CMICmdCmdTargetAttach::Acknowledge() {
  const CMICmnMIResultRecord miRecordResult(
      m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
  m_miResultRecord = miRecordResult;

  CMICmnLLDBDebugSessionInfo &rSessionInfo(
      CMICmnLLDBDebugSessionInfo::Instance());
  lldb::pid_t pid = rSessionInfo.GetProcess().GetProcessID();
  // Prod the client i.e. Eclipse with out-of-band results to help it 'continue'
  // because it is using LLDB debugger
  // Give the client '=thread-group-started,id="i1"'
  m_bHasResultRecordExtra = true;
  const CMICmnMIValueConst miValueConst2("i1");
  const CMICmnMIValueResult miValueResult2("id", miValueConst2);
  const CMIUtilString strPid(CMIUtilString::Format("%lld", pid));
  const CMICmnMIValueConst miValueConst(strPid);
  const CMICmnMIValueResult miValueResult("pid", miValueConst);
  CMICmnMIOutOfBandRecord miOutOfBand(
      CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupStarted, miValueResult2);
  miOutOfBand.Add(miValueResult);
  m_miResultRecordExtra = miOutOfBand.GetString();

  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 *CMICmdCmdTargetAttach::CreateSelf() {
  return new CMICmdCmdTargetAttach();
}

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

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

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

//++
//------------------------------------------------------------------------------------
// 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 CMICmdCmdTargetDetach::ParseArgs() { return MIstatus::success; }

//++
//------------------------------------------------------------------------------------
// 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.
//          Synopsis: -target-attach file
//          Ref:
//          http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Target-Manipulation.html#GDB_002fMI-Target-Manipulation
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdCmdTargetDetach::Execute() {
  CMICmnLLDBDebugSessionInfo &rSessionInfo(
      CMICmnLLDBDebugSessionInfo::Instance());

  lldb::SBProcess process = rSessionInfo.GetProcess();

  if (!process.IsValid()) {
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS),
                                   m_cmdData.strMiCmd.c_str()));
    return MIstatus::failure;
  }

  process.Detach();

  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 CMICmdCmdTargetDetach::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 *CMICmdCmdTargetDetach::CreateSelf() {
  return new CMICmdCmdTargetDetach();
}
