//===-- 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)), m_owned(true) {}
  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;
};

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().SetError(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 *));
}

}
}
