//===-- SBCommandReturnObject.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 "lldb/API/SBCommandReturnObject.h"
#include "SBReproducerPrivate.h"
#include "Utils.h"
#include "lldb/API/SBError.h"
#include "lldb/API/SBFile.h"
#include "lldb/API/SBStream.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Status.h"

using namespace lldb;
using namespace lldb_private;

class lldb_private::SBCommandReturnObjectImpl {
public:
  SBCommandReturnObjectImpl() : m_ptr(new CommandReturnObject(false)) {}
  SBCommandReturnObjectImpl(CommandReturnObject &ref)
      : m_ptr(&ref), m_owned(false) {}
  SBCommandReturnObjectImpl(const SBCommandReturnObjectImpl &rhs)
      : m_ptr(new CommandReturnObject(*rhs.m_ptr)), m_owned(rhs.m_owned) {}
  SBCommandReturnObjectImpl &operator=(const SBCommandReturnObjectImpl &rhs) {
    SBCommandReturnObjectImpl copy(rhs);
    std::swap(*this, copy);
    return *this;
  }
  // rvalue ctor+assignment are not used by SBCommandReturnObject.
  ~SBCommandReturnObjectImpl() {
    if (m_owned)
      delete m_ptr;
  }

  CommandReturnObject &operator*() const { return *m_ptr; }

private:
  CommandReturnObject *m_ptr;
  bool m_owned = true;
};

SBCommandReturnObject::SBCommandReturnObject()
    : m_opaque_up(new SBCommandReturnObjectImpl()) {
  LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBCommandReturnObject);
}

SBCommandReturnObject::SBCommandReturnObject(CommandReturnObject &ref)
    : m_opaque_up(new SBCommandReturnObjectImpl(ref)) {
  LLDB_RECORD_CONSTRUCTOR(SBCommandReturnObject,
                          (lldb_private::CommandReturnObject &), ref);
}

SBCommandReturnObject::SBCommandReturnObject(const SBCommandReturnObject &rhs)
    : m_opaque_up() {
  LLDB_RECORD_CONSTRUCTOR(SBCommandReturnObject,
                          (const lldb::SBCommandReturnObject &), rhs);

  m_opaque_up = clone(rhs.m_opaque_up);
}

SBCommandReturnObject &SBCommandReturnObject::
operator=(const SBCommandReturnObject &rhs) {
  LLDB_RECORD_METHOD(
      lldb::SBCommandReturnObject &,
      SBCommandReturnObject, operator=,(const lldb::SBCommandReturnObject &),
      rhs);

  if (this != &rhs)
    m_opaque_up = clone(rhs.m_opaque_up);
  return LLDB_RECORD_RESULT(*this);
}

SBCommandReturnObject::~SBCommandReturnObject() = default;

bool SBCommandReturnObject::IsValid() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandReturnObject, IsValid);
  return this->operator bool();
}
SBCommandReturnObject::operator bool() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandReturnObject, operator bool);

  // This method is not useful but it needs to stay to keep SB API stable.
  return true;
}

const char *SBCommandReturnObject::GetOutput() {
  LLDB_RECORD_METHOD_NO_ARGS(const char *, SBCommandReturnObject, GetOutput);

  ConstString output(ref().GetOutputData());
  return output.AsCString(/*value_if_empty*/ "");
}

const char *SBCommandReturnObject::GetError() {
  LLDB_RECORD_METHOD_NO_ARGS(const char *, SBCommandReturnObject, GetError);

  ConstString output(ref().GetErrorData());
  return output.AsCString(/*value_if_empty*/ "");
}

size_t SBCommandReturnObject::GetOutputSize() {
  LLDB_RECORD_METHOD_NO_ARGS(size_t, SBCommandReturnObject, GetOutputSize);

  return ref().GetOutputData().size();
}

size_t SBCommandReturnObject::GetErrorSize() {
  LLDB_RECORD_METHOD_NO_ARGS(size_t, SBCommandReturnObject, GetErrorSize);

  return ref().GetErrorData().size();
}

size_t SBCommandReturnObject::PutOutput(FILE *fh) {
  LLDB_RECORD_DUMMY(size_t, SBCommandReturnObject, PutOutput, (FILE *), fh);
  if (fh) {
    size_t num_bytes = GetOutputSize();
    if (num_bytes)
      return ::fprintf(fh, "%s", GetOutput());
  }
  return 0;
}

size_t SBCommandReturnObject::PutOutput(FileSP file_sp) {
  LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutOutput, (FileSP),
                     file_sp);
  if (!file_sp)
    return 0;
  return file_sp->Printf("%s", GetOutput());
}

size_t SBCommandReturnObject::PutOutput(SBFile file) {
  LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutOutput, (SBFile), file);
  if (!file.m_opaque_sp)
    return 0;
  return file.m_opaque_sp->Printf("%s", GetOutput());
}

size_t SBCommandReturnObject::PutError(FILE *fh) {
  LLDB_RECORD_DUMMY(size_t, SBCommandReturnObject, PutError, (FILE *), fh);
  if (fh) {
    size_t num_bytes = GetErrorSize();
    if (num_bytes)
      return ::fprintf(fh, "%s", GetError());
  }
  return 0;
}

size_t SBCommandReturnObject::PutError(FileSP file_sp) {
  LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutError, (FileSP),
                     file_sp);
  if (!file_sp)
    return 0;
  return file_sp->Printf("%s", GetError());
}

size_t SBCommandReturnObject::PutError(SBFile file) {
  LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutError, (SBFile), file);
  if (!file.m_opaque_sp)
    return 0;
  return file.m_opaque_sp->Printf("%s", GetError());
}

void SBCommandReturnObject::Clear() {
  LLDB_RECORD_METHOD_NO_ARGS(void, SBCommandReturnObject, Clear);

  ref().Clear();
}

lldb::ReturnStatus SBCommandReturnObject::GetStatus() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::ReturnStatus, SBCommandReturnObject,
                             GetStatus);

  return ref().GetStatus();
}

void SBCommandReturnObject::SetStatus(lldb::ReturnStatus status) {
  LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetStatus,
                     (lldb::ReturnStatus), status);

  ref().SetStatus(status);
}

bool SBCommandReturnObject::Succeeded() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandReturnObject, Succeeded);

  return ref().Succeeded();
}

bool SBCommandReturnObject::HasResult() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandReturnObject, HasResult);

  return ref().HasResult();
}

void SBCommandReturnObject::AppendMessage(const char *message) {
  LLDB_RECORD_METHOD(void, SBCommandReturnObject, AppendMessage, (const char *),
                     message);

  ref().AppendMessage(message);
}

void SBCommandReturnObject::AppendWarning(const char *message) {
  LLDB_RECORD_METHOD(void, SBCommandReturnObject, AppendWarning, (const char *),
                     message);

  ref().AppendWarning(message);
}

CommandReturnObject *SBCommandReturnObject::operator->() const {
  return &**m_opaque_up;
}

CommandReturnObject *SBCommandReturnObject::get() const {
  return &**m_opaque_up;
}

CommandReturnObject &SBCommandReturnObject::operator*() const {
  return **m_opaque_up;
}

CommandReturnObject &SBCommandReturnObject::ref() const {
  return **m_opaque_up;
}

bool SBCommandReturnObject::GetDescription(SBStream &description) {
  LLDB_RECORD_METHOD(bool, SBCommandReturnObject, GetDescription,
                     (lldb::SBStream &), description);

  Stream &strm = description.ref();

  description.Printf("Error:  ");
  lldb::ReturnStatus status = ref().GetStatus();
  if (status == lldb::eReturnStatusStarted)
    strm.PutCString("Started");
  else if (status == lldb::eReturnStatusInvalid)
    strm.PutCString("Invalid");
  else if (ref().Succeeded())
    strm.PutCString("Success");
  else
    strm.PutCString("Fail");

  if (GetOutputSize() > 0)
    strm.Printf("\nOutput Message:\n%s", GetOutput());

  if (GetErrorSize() > 0)
    strm.Printf("\nError Message:\n%s", GetError());

  return true;
}

void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh) {
  LLDB_RECORD_DUMMY(void, SBCommandReturnObject, SetImmediateOutputFile,
                    (FILE *), fh);

  SetImmediateOutputFile(fh, false);
}

void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh) {
  LLDB_RECORD_DUMMY(void, SBCommandReturnObject, SetImmediateErrorFile,
                    (FILE *), fh);

  SetImmediateErrorFile(fh, false);
}

void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh,
                                                   bool transfer_ownership) {
  LLDB_RECORD_DUMMY(void, SBCommandReturnObject, SetImmediateOutputFile,
                    (FILE *, bool), fh, transfer_ownership);
  FileSP file = std::make_shared<NativeFile>(fh, transfer_ownership);
  ref().SetImmediateOutputFile(file);
}

void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh,
                                                  bool transfer_ownership) {
  LLDB_RECORD_DUMMY(void, SBCommandReturnObject, SetImmediateErrorFile,
                    (FILE *, bool), fh, transfer_ownership);
  FileSP file = std::make_shared<NativeFile>(fh, transfer_ownership);
  ref().SetImmediateErrorFile(file);
}

void SBCommandReturnObject::SetImmediateOutputFile(SBFile file) {
  LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile,
                     (SBFile), file);
  ref().SetImmediateOutputFile(file.m_opaque_sp);
}

void SBCommandReturnObject::SetImmediateErrorFile(SBFile file) {
  LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile,
                     (SBFile), file);
  ref().SetImmediateErrorFile(file.m_opaque_sp);
}

void SBCommandReturnObject::SetImmediateOutputFile(FileSP file_sp) {
  LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile,
                     (FileSP), file_sp);
  SetImmediateOutputFile(SBFile(file_sp));
}

void SBCommandReturnObject::SetImmediateErrorFile(FileSP file_sp) {
  LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile,
                     (FileSP), file_sp);
  SetImmediateErrorFile(SBFile(file_sp));
}

void SBCommandReturnObject::PutCString(const char *string, int len) {
  LLDB_RECORD_METHOD(void, SBCommandReturnObject, PutCString,
                     (const char *, int), string, len);

  if (len == 0 || string == nullptr || *string == 0) {
    return;
  } else if (len > 0) {
    std::string buffer(string, len);
    ref().AppendMessage(buffer.c_str());
  } else
    ref().AppendMessage(string);
}

const char *SBCommandReturnObject::GetOutput(bool only_if_no_immediate) {
  LLDB_RECORD_METHOD(const char *, SBCommandReturnObject, GetOutput, (bool),
                     only_if_no_immediate);

  if (!only_if_no_immediate ||
      ref().GetImmediateOutputStream().get() == nullptr)
    return GetOutput();
  return nullptr;
}

const char *SBCommandReturnObject::GetError(bool only_if_no_immediate) {
  LLDB_RECORD_METHOD(const char *, SBCommandReturnObject, GetError, (bool),
                     only_if_no_immediate);

  if (!only_if_no_immediate || ref().GetImmediateErrorStream().get() == nullptr)
    return GetError();
  return nullptr;
}

size_t SBCommandReturnObject::Printf(const char *format, ...) {
  va_list args;
  va_start(args, format);
  size_t result = ref().GetOutputStream().PrintfVarArg(format, args);
  va_end(args);
  return result;
}

void SBCommandReturnObject::SetError(lldb::SBError &error,
                                     const char *fallback_error_cstr) {
  LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetError,
                     (lldb::SBError &, const char *), error,
                     fallback_error_cstr);

  if (error.IsValid())
    ref().SetError(error.ref(), fallback_error_cstr);
  else if (fallback_error_cstr)
    ref().SetError(Status(), fallback_error_cstr);
}

void SBCommandReturnObject::SetError(const char *error_cstr) {
  LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetError, (const char *),
                     error_cstr);

  if (error_cstr)
    ref().AppendError(error_cstr);
}

namespace lldb_private {
namespace repro {

template <>
void RegisterMethods<SBCommandReturnObject>(Registry &R) {
  LLDB_REGISTER_CONSTRUCTOR(SBCommandReturnObject, ());
  LLDB_REGISTER_CONSTRUCTOR(SBCommandReturnObject,
                            (lldb_private::CommandReturnObject &));
  LLDB_REGISTER_CONSTRUCTOR(SBCommandReturnObject,
                            (const lldb::SBCommandReturnObject &));
  LLDB_REGISTER_METHOD(
      lldb::SBCommandReturnObject &,
      SBCommandReturnObject, operator=,(const lldb::SBCommandReturnObject &));
  LLDB_REGISTER_METHOD_CONST(bool, SBCommandReturnObject, IsValid, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBCommandReturnObject, operator bool, ());
  LLDB_REGISTER_METHOD(const char *, SBCommandReturnObject, GetOutput, ());
  LLDB_REGISTER_METHOD(const char *, SBCommandReturnObject, GetError, ());
  LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, GetOutputSize, ());
  LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, GetErrorSize, ());
  LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutOutput, (FILE *));
  LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutError, (FILE *));
  LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutOutput, (SBFile));
  LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutError, (SBFile));
  LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutOutput, (FileSP));
  LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutError, (FileSP));
  LLDB_REGISTER_METHOD(void, SBCommandReturnObject, Clear, ());
  LLDB_REGISTER_METHOD(lldb::ReturnStatus, SBCommandReturnObject, GetStatus,
                       ());
  LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetStatus,
                       (lldb::ReturnStatus));
  LLDB_REGISTER_METHOD(bool, SBCommandReturnObject, Succeeded, ());
  LLDB_REGISTER_METHOD(bool, SBCommandReturnObject, HasResult, ());
  LLDB_REGISTER_METHOD(void, SBCommandReturnObject, AppendMessage,
                       (const char *));
  LLDB_REGISTER_METHOD(void, SBCommandReturnObject, AppendWarning,
                       (const char *));
  LLDB_REGISTER_METHOD(bool, SBCommandReturnObject, GetDescription,
                       (lldb::SBStream &));
  LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile,
                       (FILE *));
  LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile,
                       (FILE *));
  LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile,
                       (SBFile));
  LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile,
                       (SBFile));
  LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile,
                       (FileSP));
  LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile,
                       (FileSP));
  LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile,
                       (FILE *, bool));
  LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile,
                       (FILE *, bool));
  LLDB_REGISTER_METHOD(void, SBCommandReturnObject, PutCString,
                       (const char *, int));
  LLDB_REGISTER_METHOD(const char *, SBCommandReturnObject, GetOutput,
                       (bool));
  LLDB_REGISTER_METHOD(const char *, SBCommandReturnObject, GetError, (bool));
  LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetError,
                       (lldb::SBError &, const char *));
  LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetError, (const char *));
}

}
}
