//===-- MICmdCmdSymbol.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:    CMICmdCmdSymbolListLines     implementation.

// Third Party Headers:
#include "llvm/ADT/Twine.h"
#include "lldb/API/SBAddress.h"
#include "lldb/API/SBLineEntry.h"
#include "lldb/API/SBFileSpec.h"
#include "lldb/API/SBCompileUnit.h"
#include "lldb/API/SBSymbolContext.h"
#include "lldb/API/SBSymbolContextList.h"

// In-house headers:
#include "MICmdArgValFile.h"
#include "MICmdCmdSymbol.h"
#include "MICmnLLDBDebugSessionInfo.h"
#include "MICmnMIResultRecord.h"
#include "MICmnMIValueTuple.h"
#include "MICmnMIValueResult.h"

namespace {
const CMICmnMIValueTuple
CreateMITuplePCLine(const uint32_t addr, const uint32_t line_number) {
  const CMICmnMIValueConst miValueConstAddr("0x" + llvm::Twine::utohexstr(addr).str());
  const CMICmnMIValueConst miValueConstLine(llvm::Twine(line_number).str());
  const CMICmnMIValueResult miValueResultAddr("pc", miValueConstAddr);
  const CMICmnMIValueResult miValueResultLine("line", miValueConstLine);
  CMICmnMIValueTuple miValueTuple(miValueResultAddr);
  miValueTuple.Add(miValueResultLine);
  return miValueTuple;
}
} // namespace

using namespace lldb; // For operator==(const SBAddress &, const SBAddress &).

//++
//------------------------------------------------------------------------------------
// Details: CMICmdCmdSymbolListLines constructor.
// Type:    Method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmdCmdSymbolListLines::CMICmdCmdSymbolListLines()
    : m_resultList(false), m_constStrArgNameFile("file") {
  // Command factory matches this name with that received from the stdin stream
  m_strMiCmd = "symbol-list-lines";

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

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

//++
//------------------------------------------------------------------------------------
// 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 CMICmdCmdSymbolListLines::ParseArgs() {
  m_setCmdArgs.Add(new CMICmdArgValFile(m_constStrArgNameFile, 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: -symbol-list-lines file
//          Ref:
//          http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Symbol-Query.html#GDB_002fMI-Symbol-Query
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdCmdSymbolListLines::Execute() {
  CMICMDBASE_GETOPTION(pArgFile, File, m_constStrArgNameFile);

  const auto &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
  if (rSessionInfo.GetTarget() == rSessionInfo.GetDebugger().GetDummyTarget()) {
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT),
                                   m_cmdData.strMiCmd.c_str()));
    return MIstatus::failure;
  }

  const lldb::SBFileSpec source_file_spec(pArgFile->GetValue().c_str(), true);
  const char *source_file_name = source_file_spec.GetFilename();
  const char *source_file_directory = source_file_spec.GetDirectory();
  const bool has_path = source_file_directory;

  lldb::SBSymbolContextList sc_cu_list =
      CMICmnLLDBDebugSessionInfo::Instance().GetTarget().FindCompileUnits(
          source_file_spec);

  bool found_something = false;
  for (uint32_t i = 0, e = sc_cu_list.GetSize(); i < e; ++i) {
    const lldb::SBCompileUnit cu =
        sc_cu_list.GetContextAtIndex(i).GetCompileUnit();
    for (uint32_t j = 0, e = cu.GetNumLineEntries(); j < e; ++j) {
      const lldb::SBLineEntry line = cu.GetLineEntryAtIndex(j);
      const lldb::SBFileSpec line_spec = line.GetFileSpec();
      if (line_spec.GetFilename() == source_file_name) {
        if (has_path && (line_spec.GetDirectory() != source_file_directory))
          continue;
        // We don't need a line with start address equals to end one,
        // so just skip it.
        const lldb::SBAddress line_start_address = line.GetStartAddress();
        const lldb::SBAddress line_end_address = line.GetEndAddress();
        if (line_start_address == line_end_address)
          continue;
        // We have a matching line.
        found_something = true;
        m_resultList.Add(CreateMITuplePCLine(
            line_start_address.GetFileAddress(),
            line.GetLine()));
      }
    }
  }
  if (!found_something) {
    SetError(MIRSRC(IDS_UTIL_FILE_ERR_INVALID_PATHNAME));
    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 CMICmdCmdSymbolListLines::Acknowledge() {
  // MI print "%s^done,lines=[{pc=\"%d\",line=\"%d\"}...]"
  const CMICmnMIValueResult miValueResult("lines", m_resultList);
  m_miResultRecord = CMICmnMIResultRecord(
      m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
      miValueResult);
  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 *CMICmdCmdSymbolListLines::CreateSelf() {
  return new CMICmdCmdSymbolListLines();
}
