//===-- MICmdCmdThread.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
//
//===----------------------------------------------------------------------===//

// Overview:    CMICmdCmdThreadInfo     implementation.

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

// In-house headers:
#include "MICmdArgValNumber.h"
#include "MICmdCmdThread.h"
#include "MICmnLLDBDebugSessionInfo.h"
#include "MICmnLLDBDebugger.h"
#include "MICmnMIResultRecord.h"
#include "MICmnMIValueConst.h"

//++
// Details: CMICmdCmdThreadInfo constructor.
// Type:    Method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmdCmdThreadInfo::CMICmdCmdThreadInfo()
    : m_bSingleThread(false), m_bThreadInvalid(true),
      m_constStrArgNamedThreadId("thread-id"), m_bHasCurrentThread(false) {
  // Command factory matches this name with that received from the stdin stream
  m_strMiCmd = "thread-info";

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

//++
// Details: CMICmdCmdThreadInfo destructor.
// Type:    Overrideable.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmdCmdThreadInfo::~CMICmdCmdThreadInfo() { m_vecMIValueTuple.clear(); }

//++
// 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 CMICmdCmdThreadInfo::ParseArgs() {
  m_setCmdArgs.Add(
      new CMICmdArgValNumber(m_constStrArgNamedThreadId, 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.
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdCmdThreadInfo::Execute() {
  CMICMDBASE_GETOPTION(pArgThreadId, Number, m_constStrArgNamedThreadId);
  MIuint nThreadId = 0;
  if (pArgThreadId->GetFound() && pArgThreadId->GetValid()) {
    m_bSingleThread = true;
    nThreadId = static_cast<MIuint>(pArgThreadId->GetValue());
  }

  CMICmnLLDBDebugSessionInfo &rSessionInfo(
      CMICmnLLDBDebugSessionInfo::Instance());
  lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
  lldb::SBThread thread = sbProcess.GetSelectedThread();

  if (m_bSingleThread) {
    thread = sbProcess.GetThreadByIndexID(nThreadId);
    m_bThreadInvalid = !thread.IsValid();
    if (m_bThreadInvalid)
      return MIstatus::success;

    CMICmnMIValueTuple miTuple;
    if (!rSessionInfo.MIResponseFormThreadInfo(
            m_cmdData, thread,
            CMICmnLLDBDebugSessionInfo::eThreadInfoFormat_AllFrames, miTuple))
      return MIstatus::failure;

    m_miValueTupleThread = miTuple;

    return MIstatus::success;
  }

  // Multiple threads
  m_vecMIValueTuple.clear();
  const MIuint nThreads = sbProcess.GetNumThreads();
  for (MIuint i = 0; i < nThreads; i++) {
    lldb::SBThread thread = sbProcess.GetThreadAtIndex(i);
    if (thread.IsValid()) {
      CMICmnMIValueTuple miTuple;
      if (!rSessionInfo.MIResponseFormThreadInfo(
              m_cmdData, thread,
              CMICmnLLDBDebugSessionInfo::eThreadInfoFormat_AllFrames, miTuple))
        return MIstatus::failure;

      m_vecMIValueTuple.push_back(miTuple);
    }
  }

  // -thread-info with multiple threads ends with the current thread id if any
  if (thread.IsValid()) {
    const CMIUtilString strId(CMIUtilString::Format("%d", thread.GetIndexID()));
    CMICmnMIValueConst miValueCurrThreadId(strId);
    m_miValueCurrThreadId = miValueCurrThreadId;
    m_bHasCurrentThread = true;
  }

  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 CMICmdCmdThreadInfo::Acknowledge() {
  if (m_bSingleThread) {
    if (m_bThreadInvalid) {
      const CMICmnMIValueConst miValueConst("invalid thread id");
      const CMICmnMIValueResult miValueResult("msg", miValueConst);
      const CMICmnMIResultRecord miRecordResult(
          m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
          miValueResult);
      m_miResultRecord = miRecordResult;
      return MIstatus::success;
    }

    // MI print
    // "%s^done,threads=[{id=\"%d\",target-id=\"%s\",frame={},state=\"%s\"}]
    const CMICmnMIValueList miValueList(m_miValueTupleThread);
    const CMICmnMIValueResult miValueResult("threads", miValueList);
    const CMICmnMIResultRecord miRecordResult(
        m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
        miValueResult);
    m_miResultRecord = miRecordResult;
    return MIstatus::success;
  }

  // Build up a list of thread information from tuples
  VecMIValueTuple_t::const_iterator it = m_vecMIValueTuple.begin();
  if (it == m_vecMIValueTuple.end()) {
    const CMICmnMIValueConst miValueConst("[]");
    const CMICmnMIValueResult miValueResult("threads", miValueConst);
    const CMICmnMIResultRecord miRecordResult(
        m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
        miValueResult);
    m_miResultRecord = miRecordResult;
    return MIstatus::success;
  }
  CMICmnMIValueList miValueList(*it);
  ++it;
  while (it != m_vecMIValueTuple.end()) {
    const CMICmnMIValueTuple &rTuple(*it);
    miValueList.Add(rTuple);

    // Next
    ++it;
  }

  CMICmnMIValueResult miValueResult("threads", miValueList);
  if (m_bHasCurrentThread) {
    CMIUtilString strCurrThreadId = "current-thread-id";
    miValueResult.Add(strCurrThreadId, m_miValueCurrThreadId);
  }
  const CMICmnMIResultRecord miRecordResult(
      m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
      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 *CMICmdCmdThreadInfo::CreateSelf() {
  return new CMICmdCmdThreadInfo();
}
