//===-- SBTypeSynthetic.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/SBTypeSynthetic.h"
#include "SBReproducerPrivate.h"

#include "lldb/API/SBStream.h"

#include "lldb/DataFormatters/DataVisualization.h"

using namespace lldb;
using namespace lldb_private;

SBTypeSynthetic::SBTypeSynthetic() : m_opaque_sp() {
  LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBTypeSynthetic);
}

SBTypeSynthetic SBTypeSynthetic::CreateWithClassName(const char *data,
                                                     uint32_t options) {
  LLDB_RECORD_STATIC_METHOD(lldb::SBTypeSynthetic, SBTypeSynthetic,
                            CreateWithClassName, (const char *, uint32_t), data,
                            options);

  if (!data || data[0] == 0)
    return LLDB_RECORD_RESULT(SBTypeSynthetic());
  return LLDB_RECORD_RESULT(SBTypeSynthetic(ScriptedSyntheticChildrenSP(
      new ScriptedSyntheticChildren(options, data, ""))));
}

SBTypeSynthetic SBTypeSynthetic::CreateWithScriptCode(const char *data,
                                                      uint32_t options) {
  LLDB_RECORD_STATIC_METHOD(lldb::SBTypeSynthetic, SBTypeSynthetic,
                            CreateWithScriptCode, (const char *, uint32_t),
                            data, options);

  if (!data || data[0] == 0)
    return LLDB_RECORD_RESULT(SBTypeSynthetic());
  return LLDB_RECORD_RESULT(SBTypeSynthetic(ScriptedSyntheticChildrenSP(
      new ScriptedSyntheticChildren(options, "", data))));
}

SBTypeSynthetic::SBTypeSynthetic(const lldb::SBTypeSynthetic &rhs)
    : m_opaque_sp(rhs.m_opaque_sp) {
  LLDB_RECORD_CONSTRUCTOR(SBTypeSynthetic, (const lldb::SBTypeSynthetic &),
                          rhs);
}

SBTypeSynthetic::~SBTypeSynthetic() = default;

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

  return m_opaque_sp.get() != nullptr;
}

bool SBTypeSynthetic::IsClassCode() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBTypeSynthetic, IsClassCode);

  if (!IsValid())
    return false;
  const char *code = m_opaque_sp->GetPythonCode();
  return (code && *code);
}

bool SBTypeSynthetic::IsClassName() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBTypeSynthetic, IsClassName);

  if (!IsValid())
    return false;
  return !IsClassCode();
}

const char *SBTypeSynthetic::GetData() {
  LLDB_RECORD_METHOD_NO_ARGS(const char *, SBTypeSynthetic, GetData);

  if (!IsValid())
    return nullptr;
  if (IsClassCode())
    return m_opaque_sp->GetPythonCode();
  else
    return m_opaque_sp->GetPythonClassName();
}

void SBTypeSynthetic::SetClassName(const char *data) {
  LLDB_RECORD_METHOD(void, SBTypeSynthetic, SetClassName, (const char *), data);

  if (IsValid() && data && *data)
    m_opaque_sp->SetPythonClassName(data);
}

void SBTypeSynthetic::SetClassCode(const char *data) {
  LLDB_RECORD_METHOD(void, SBTypeSynthetic, SetClassCode, (const char *), data);

  if (IsValid() && data && *data)
    m_opaque_sp->SetPythonCode(data);
}

uint32_t SBTypeSynthetic::GetOptions() {
  LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBTypeSynthetic, GetOptions);

  if (!IsValid())
    return lldb::eTypeOptionNone;
  return m_opaque_sp->GetOptions();
}

void SBTypeSynthetic::SetOptions(uint32_t value) {
  LLDB_RECORD_METHOD(void, SBTypeSynthetic, SetOptions, (uint32_t), value);

  if (!CopyOnWrite_Impl())
    return;
  m_opaque_sp->SetOptions(value);
}

bool SBTypeSynthetic::GetDescription(lldb::SBStream &description,
                                     lldb::DescriptionLevel description_level) {
  LLDB_RECORD_METHOD(bool, SBTypeSynthetic, GetDescription,
                     (lldb::SBStream &, lldb::DescriptionLevel), description,
                     description_level);

  if (m_opaque_sp) {
    description.Printf("%s\n", m_opaque_sp->GetDescription().c_str());
    return true;
  }
  return false;
}

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

  if (this != &rhs) {
    m_opaque_sp = rhs.m_opaque_sp;
  }
  return LLDB_RECORD_RESULT(*this);
}

bool SBTypeSynthetic::operator==(lldb::SBTypeSynthetic &rhs) {
  LLDB_RECORD_METHOD(
      bool, SBTypeSynthetic, operator==,(lldb::SBTypeSynthetic &), rhs);

  if (!IsValid())
    return !rhs.IsValid();
  return m_opaque_sp == rhs.m_opaque_sp;
}

bool SBTypeSynthetic::IsEqualTo(lldb::SBTypeSynthetic &rhs) {
  LLDB_RECORD_METHOD(bool, SBTypeSynthetic, IsEqualTo,
                     (lldb::SBTypeSynthetic &), rhs);

  if (!IsValid())
    return !rhs.IsValid();

  if (m_opaque_sp->IsScripted() != rhs.m_opaque_sp->IsScripted())
    return false;

  if (IsClassCode() != rhs.IsClassCode())
    return false;

  if (strcmp(GetData(), rhs.GetData()))
    return false;

  return GetOptions() == rhs.GetOptions();
}

bool SBTypeSynthetic::operator!=(lldb::SBTypeSynthetic &rhs) {
  LLDB_RECORD_METHOD(
      bool, SBTypeSynthetic, operator!=,(lldb::SBTypeSynthetic &), rhs);

  if (!IsValid())
    return !rhs.IsValid();
  return m_opaque_sp != rhs.m_opaque_sp;
}

lldb::ScriptedSyntheticChildrenSP SBTypeSynthetic::GetSP() {
  return m_opaque_sp;
}

void SBTypeSynthetic::SetSP(
    const lldb::ScriptedSyntheticChildrenSP &TypeSynthetic_impl_sp) {
  m_opaque_sp = TypeSynthetic_impl_sp;
}

SBTypeSynthetic::SBTypeSynthetic(
    const lldb::ScriptedSyntheticChildrenSP &TypeSynthetic_impl_sp)
    : m_opaque_sp(TypeSynthetic_impl_sp) {}

bool SBTypeSynthetic::CopyOnWrite_Impl() {
  if (!IsValid())
    return false;
  if (m_opaque_sp.unique())
    return true;

  ScriptedSyntheticChildrenSP new_sp(new ScriptedSyntheticChildren(
      m_opaque_sp->GetOptions(), m_opaque_sp->GetPythonClassName(),
      m_opaque_sp->GetPythonCode()));

  SetSP(new_sp);

  return true;
}

namespace lldb_private {
namespace repro {

template <>
void RegisterMethods<SBTypeSynthetic>(Registry &R) {
  LLDB_REGISTER_CONSTRUCTOR(SBTypeSynthetic, ());
  LLDB_REGISTER_STATIC_METHOD(lldb::SBTypeSynthetic, SBTypeSynthetic,
                              CreateWithClassName, (const char *, uint32_t));
  LLDB_REGISTER_STATIC_METHOD(lldb::SBTypeSynthetic, SBTypeSynthetic,
                              CreateWithScriptCode, (const char *, uint32_t));
  LLDB_REGISTER_CONSTRUCTOR(SBTypeSynthetic, (const lldb::SBTypeSynthetic &));
  LLDB_REGISTER_METHOD_CONST(bool, SBTypeSynthetic, IsValid, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBTypeSynthetic, operator bool, ());
  LLDB_REGISTER_METHOD(bool, SBTypeSynthetic, IsClassCode, ());
  LLDB_REGISTER_METHOD(bool, SBTypeSynthetic, IsClassName, ());
  LLDB_REGISTER_METHOD(const char *, SBTypeSynthetic, GetData, ());
  LLDB_REGISTER_METHOD(void, SBTypeSynthetic, SetClassName, (const char *));
  LLDB_REGISTER_METHOD(void, SBTypeSynthetic, SetClassCode, (const char *));
  LLDB_REGISTER_METHOD(uint32_t, SBTypeSynthetic, GetOptions, ());
  LLDB_REGISTER_METHOD(void, SBTypeSynthetic, SetOptions, (uint32_t));
  LLDB_REGISTER_METHOD(bool, SBTypeSynthetic, GetDescription,
                       (lldb::SBStream &, lldb::DescriptionLevel));
  LLDB_REGISTER_METHOD(
      lldb::SBTypeSynthetic &,
      SBTypeSynthetic, operator=,(const lldb::SBTypeSynthetic &));
  LLDB_REGISTER_METHOD(bool,
                       SBTypeSynthetic, operator==,(lldb::SBTypeSynthetic &));
  LLDB_REGISTER_METHOD(bool, SBTypeSynthetic, IsEqualTo,
                       (lldb::SBTypeSynthetic &));
  LLDB_REGISTER_METHOD(bool,
                       SBTypeSynthetic, operator!=,(lldb::SBTypeSynthetic &));
}

}
}
