//===-- CommandObjectThreadTraceExportCTF.cpp -----------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "CommandObjectThreadTraceExportCTF.h"

#include "../common/TraceHTR.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Trace.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::ctf;
using namespace llvm;

// CommandObjectThreadTraceExportCTF

#define LLDB_OPTIONS_thread_trace_export_ctf
#include "TraceExporterCTFCommandOptions.inc"

Status CommandObjectThreadTraceExportCTF::CommandOptions::SetOptionValue(
    uint32_t option_idx, llvm::StringRef option_arg,
    ExecutionContext *execution_context) {
  Status error;
  const int short_option = m_getopt_table[option_idx].val;

  switch (short_option) {
  case 'f': {
    m_file.assign(std::string(option_arg));
    break;
  }
  case 't': {
    int64_t thread_index;
    if (option_arg.empty() || option_arg.getAsInteger(0, thread_index) ||
        thread_index < 0)
      error.SetErrorStringWithFormat("invalid integer value for option '%s'",
                                     option_arg.str().c_str());
    else
      m_thread_index = thread_index;
    break;
  }
  default:
    llvm_unreachable("Unimplemented option");
  }
  return error;
}

void CommandObjectThreadTraceExportCTF::CommandOptions::OptionParsingStarting(
    ExecutionContext *execution_context) {
  m_file.clear();
  m_thread_index = None;
}

llvm::ArrayRef<OptionDefinition>
CommandObjectThreadTraceExportCTF::CommandOptions::GetDefinitions() {
  return llvm::makeArrayRef(g_thread_trace_export_ctf_options);
}

bool CommandObjectThreadTraceExportCTF::DoExecute(Args &command,
                                                  CommandReturnObject &result) {
  const TraceSP &trace_sp = m_exe_ctx.GetTargetSP()->GetTrace();
  Process *process = m_exe_ctx.GetProcessPtr();
  Thread *thread = m_options.m_thread_index
                       ? process->GetThreadList()
                             .FindThreadByIndexID(*m_options.m_thread_index)
                             .get()
                       : GetDefaultThread();

  if (thread == nullptr) {
    const uint32_t num_threads = process->GetThreadList().GetSize();
    size_t tid = m_options.m_thread_index ? *m_options.m_thread_index
                                          : LLDB_INVALID_THREAD_ID;
    result.AppendErrorWithFormatv(
        "Thread index {0} is out of range (valid values are 1 - {1}).\n", tid,
        num_threads);
    return false;
  } else {
    TraceHTR htr(*thread, *trace_sp->GetCursor(*thread));
    htr.ExecutePasses();
    if (llvm::Error err = htr.Export(m_options.m_file)) {
      result.AppendErrorWithFormat("%s\n", toString(std::move(err)).c_str());
      return false;
    } else {
      return true;
    }
  }
}
