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

#include "lldb/Interpreter/CommandReturnObject.h"

#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"

using namespace lldb;
using namespace lldb_private;

static void DumpStringToStreamWithNewline(Stream &strm, const std::string &s,
                                          bool add_newline_if_empty) {
  bool add_newline = false;
  if (s.empty()) {
    add_newline = add_newline_if_empty;
  } else {
    // We already checked for empty above, now make sure there is a newline in
    // the error, and if there isn't one, add one.
    strm.Write(s.c_str(), s.size());

    const char last_char = *s.rbegin();
    add_newline = last_char != '\n' && last_char != '\r';
  }
  if (add_newline)
    strm.EOL();
}

CommandReturnObject::CommandReturnObject()
    : m_out_stream(), m_err_stream(), m_status(eReturnStatusStarted),
      m_did_change_process_state(false), m_interactive(true),
      m_abnormal_stop_was_expected(false) {}

CommandReturnObject::~CommandReturnObject() {}

void CommandReturnObject::AppendErrorWithFormat(const char *format, ...) {
  if (!format)
    return;
  va_list args;
  va_start(args, format);
  StreamString sstrm;
  sstrm.PrintfVarArg(format, args);
  va_end(args);

  const std::string &s = sstrm.GetString();
  if (!s.empty()) {
    Stream &error_strm = GetErrorStream();
    error_strm.PutCString("error: ");
    DumpStringToStreamWithNewline(error_strm, s, false);
  }
}

void CommandReturnObject::AppendMessageWithFormat(const char *format, ...) {
  if (!format)
    return;
  va_list args;
  va_start(args, format);
  StreamString sstrm;
  sstrm.PrintfVarArg(format, args);
  va_end(args);

  GetOutputStream() << sstrm.GetString();
}

void CommandReturnObject::AppendWarningWithFormat(const char *format, ...) {
  if (!format)
    return;
  va_list args;
  va_start(args, format);
  StreamString sstrm;
  sstrm.PrintfVarArg(format, args);
  va_end(args);

  GetErrorStream() << "warning: " << sstrm.GetString();
}

void CommandReturnObject::AppendMessage(llvm::StringRef in_string) {
  if (in_string.empty())
    return;
  GetOutputStream() << in_string << "\n";
}

void CommandReturnObject::AppendWarning(llvm::StringRef in_string) {
  if (in_string.empty())
    return;
  GetErrorStream() << "warning: " << in_string << "\n";
}

// Similar to AppendWarning, but do not prepend 'warning: ' to message, and
// don't append "\n" to the end of it.

void CommandReturnObject::AppendRawWarning(llvm::StringRef in_string) {
  if (in_string.empty())
    return;
  GetErrorStream() << in_string;
}

void CommandReturnObject::AppendError(llvm::StringRef in_string) {
  if (in_string.empty())
    return;
  GetErrorStream() << "error: " << in_string << "\n";
}

void CommandReturnObject::SetError(const Status &error,
                                   const char *fallback_error_cstr) {
  const char *error_cstr = error.AsCString();
  if (error_cstr == nullptr)
    error_cstr = fallback_error_cstr;
  SetError(error_cstr);
}

void CommandReturnObject::SetError(llvm::StringRef error_str) {
  if (error_str.empty())
    return;

  AppendError(error_str);
  SetStatus(eReturnStatusFailed);
}

// Similar to AppendError, but do not prepend 'Status: ' to message, and don't
// append "\n" to the end of it.

void CommandReturnObject::AppendRawError(llvm::StringRef in_string) {
  if (in_string.empty())
    return;
  GetErrorStream() << in_string;
}

void CommandReturnObject::SetStatus(ReturnStatus status) { m_status = status; }

ReturnStatus CommandReturnObject::GetStatus() { return m_status; }

bool CommandReturnObject::Succeeded() {
  return m_status <= eReturnStatusSuccessContinuingResult;
}

bool CommandReturnObject::HasResult() {
  return (m_status == eReturnStatusSuccessFinishResult ||
          m_status == eReturnStatusSuccessContinuingResult);
}

void CommandReturnObject::Clear() {
  lldb::StreamSP stream_sp;
  stream_sp = m_out_stream.GetStreamAtIndex(eStreamStringIndex);
  if (stream_sp)
    static_cast<StreamString *>(stream_sp.get())->Clear();
  stream_sp = m_err_stream.GetStreamAtIndex(eStreamStringIndex);
  if (stream_sp)
    static_cast<StreamString *>(stream_sp.get())->Clear();
  m_status = eReturnStatusStarted;
  m_did_change_process_state = false;
  m_interactive = true;
}

bool CommandReturnObject::GetDidChangeProcessState() {
  return m_did_change_process_state;
}

void CommandReturnObject::SetDidChangeProcessState(bool b) {
  m_did_change_process_state = b;
}

bool CommandReturnObject::GetInteractive() const { return m_interactive; }

void CommandReturnObject::SetInteractive(bool b) { m_interactive = b; }
