//===-- SBTypeSummary.cpp -----------------------------------------*- C++
//-*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/API/SBTypeSummary.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBValue.h"
#include "lldb/DataFormatters/DataVisualization.h"

#include "llvm/Support/Casting.h"

using namespace lldb;
using namespace lldb_private;

SBTypeSummaryOptions::SBTypeSummaryOptions() {
  m_opaque_ap.reset(new TypeSummaryOptions());
}

SBTypeSummaryOptions::SBTypeSummaryOptions(
    const lldb::SBTypeSummaryOptions &rhs) {
  if (rhs.m_opaque_ap)
    m_opaque_ap.reset(new TypeSummaryOptions(*rhs.m_opaque_ap.get()));
  else
    m_opaque_ap.reset(new TypeSummaryOptions());
}

SBTypeSummaryOptions::~SBTypeSummaryOptions() {}

bool SBTypeSummaryOptions::IsValid() { return m_opaque_ap.get(); }

lldb::LanguageType SBTypeSummaryOptions::GetLanguage() {
  if (IsValid())
    return m_opaque_ap->GetLanguage();
  return lldb::eLanguageTypeUnknown;
}

lldb::TypeSummaryCapping SBTypeSummaryOptions::GetCapping() {
  if (IsValid())
    return m_opaque_ap->GetCapping();
  return eTypeSummaryCapped;
}

void SBTypeSummaryOptions::SetLanguage(lldb::LanguageType l) {
  if (IsValid())
    m_opaque_ap->SetLanguage(l);
}

void SBTypeSummaryOptions::SetCapping(lldb::TypeSummaryCapping c) {
  if (IsValid())
    m_opaque_ap->SetCapping(c);
}

lldb_private::TypeSummaryOptions *SBTypeSummaryOptions::operator->() {
  return m_opaque_ap.get();
}

const lldb_private::TypeSummaryOptions *SBTypeSummaryOptions::
operator->() const {
  return m_opaque_ap.get();
}

lldb_private::TypeSummaryOptions *SBTypeSummaryOptions::get() {
  return m_opaque_ap.get();
}

lldb_private::TypeSummaryOptions &SBTypeSummaryOptions::ref() {
  return *m_opaque_ap.get();
}

const lldb_private::TypeSummaryOptions &SBTypeSummaryOptions::ref() const {
  return *m_opaque_ap.get();
}

SBTypeSummaryOptions::SBTypeSummaryOptions(
    const lldb_private::TypeSummaryOptions *lldb_object_ptr) {
  SetOptions(lldb_object_ptr);
}

void SBTypeSummaryOptions::SetOptions(
    const lldb_private::TypeSummaryOptions *lldb_object_ptr) {
  if (lldb_object_ptr)
    m_opaque_ap.reset(new TypeSummaryOptions(*lldb_object_ptr));
  else
    m_opaque_ap.reset(new TypeSummaryOptions());
}

SBTypeSummary::SBTypeSummary() : m_opaque_sp() {}

SBTypeSummary SBTypeSummary::CreateWithSummaryString(const char *data,
                                                     uint32_t options) {
  if (!data || data[0] == 0)
    return SBTypeSummary();

  return SBTypeSummary(
      TypeSummaryImplSP(new StringSummaryFormat(options, data)));
}

SBTypeSummary SBTypeSummary::CreateWithFunctionName(const char *data,
                                                    uint32_t options) {
  if (!data || data[0] == 0)
    return SBTypeSummary();

  return SBTypeSummary(
      TypeSummaryImplSP(new ScriptSummaryFormat(options, data)));
}

SBTypeSummary SBTypeSummary::CreateWithScriptCode(const char *data,
                                                  uint32_t options) {
  if (!data || data[0] == 0)
    return SBTypeSummary();

  return SBTypeSummary(
      TypeSummaryImplSP(new ScriptSummaryFormat(options, "", data)));
}

SBTypeSummary SBTypeSummary::CreateWithCallback(FormatCallback cb,
                                                uint32_t options,
                                                const char *description) {
  SBTypeSummary retval;
  if (cb) {
    retval.SetSP(TypeSummaryImplSP(new CXXFunctionSummaryFormat(
        options,
        [cb](ValueObject &valobj, Stream &stm,
             const TypeSummaryOptions &opt) -> bool {
          SBStream stream;
          SBValue sb_value(valobj.GetSP());
          SBTypeSummaryOptions options(&opt);
          if (!cb(sb_value, options, stream))
            return false;
          stm.Write(stream.GetData(), stream.GetSize());
          return true;
        },
        description ? description : "callback summary formatter")));
  }

  return retval;
}

SBTypeSummary::SBTypeSummary(const lldb::SBTypeSummary &rhs)
    : m_opaque_sp(rhs.m_opaque_sp) {}

SBTypeSummary::~SBTypeSummary() {}

bool SBTypeSummary::IsValid() const { return m_opaque_sp.get() != NULL; }

bool SBTypeSummary::IsFunctionCode() {
  if (!IsValid())
    return false;
  if (ScriptSummaryFormat *script_summary_ptr =
          llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) {
    const char *ftext = script_summary_ptr->GetPythonScript();
    return (ftext && *ftext != 0);
  }
  return false;
}

bool SBTypeSummary::IsFunctionName() {
  if (!IsValid())
    return false;
  if (ScriptSummaryFormat *script_summary_ptr =
          llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) {
    const char *ftext = script_summary_ptr->GetPythonScript();
    return (!ftext || *ftext == 0);
  }
  return false;
}

bool SBTypeSummary::IsSummaryString() {
  if (!IsValid())
    return false;

  return m_opaque_sp->GetKind() == TypeSummaryImpl::Kind::eSummaryString;
}

const char *SBTypeSummary::GetData() {
  if (!IsValid())
    return NULL;
  if (ScriptSummaryFormat *script_summary_ptr =
          llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) {
    const char *fname = script_summary_ptr->GetFunctionName();
    const char *ftext = script_summary_ptr->GetPythonScript();
    if (ftext && *ftext)
      return ftext;
    return fname;
  } else if (StringSummaryFormat *string_summary_ptr =
                 llvm::dyn_cast<StringSummaryFormat>(m_opaque_sp.get()))
    return string_summary_ptr->GetSummaryString();
  return nullptr;
}

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

void SBTypeSummary::SetOptions(uint32_t value) {
  if (!CopyOnWrite_Impl())
    return;
  m_opaque_sp->SetOptions(value);
}

void SBTypeSummary::SetSummaryString(const char *data) {
  if (!IsValid())
    return;
  if (!llvm::isa<StringSummaryFormat>(m_opaque_sp.get()))
    ChangeSummaryType(false);
  if (StringSummaryFormat *string_summary_ptr =
          llvm::dyn_cast<StringSummaryFormat>(m_opaque_sp.get()))
    string_summary_ptr->SetSummaryString(data);
}

void SBTypeSummary::SetFunctionName(const char *data) {
  if (!IsValid())
    return;
  if (!llvm::isa<ScriptSummaryFormat>(m_opaque_sp.get()))
    ChangeSummaryType(true);
  if (ScriptSummaryFormat *script_summary_ptr =
          llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get()))
    script_summary_ptr->SetFunctionName(data);
}

void SBTypeSummary::SetFunctionCode(const char *data) {
  if (!IsValid())
    return;
  if (!llvm::isa<ScriptSummaryFormat>(m_opaque_sp.get()))
    ChangeSummaryType(true);
  if (ScriptSummaryFormat *script_summary_ptr =
          llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get()))
    script_summary_ptr->SetPythonScript(data);
}

bool SBTypeSummary::GetDescription(lldb::SBStream &description,
                                   lldb::DescriptionLevel description_level) {
  if (!CopyOnWrite_Impl())
    return false;
  else {
    description.Printf("%s\n", m_opaque_sp->GetDescription().c_str());
    return true;
  }
}

bool SBTypeSummary::DoesPrintValue(lldb::SBValue value) {
  if (!IsValid())
    return false;
  lldb::ValueObjectSP value_sp = value.GetSP();
  return m_opaque_sp->DoesPrintValue(value_sp.get());
}

lldb::SBTypeSummary &SBTypeSummary::operator=(const lldb::SBTypeSummary &rhs) {
  if (this != &rhs) {
    m_opaque_sp = rhs.m_opaque_sp;
  }
  return *this;
}

bool SBTypeSummary::operator==(lldb::SBTypeSummary &rhs) {
  if (IsValid() == false)
    return !rhs.IsValid();
  return m_opaque_sp == rhs.m_opaque_sp;
}

bool SBTypeSummary::IsEqualTo(lldb::SBTypeSummary &rhs) {
  if (IsValid()) {
    // valid and invalid are different
    if (!rhs.IsValid())
      return false;
  } else {
    // invalid and valid are different
    if (rhs.IsValid())
      return false;
    else
      // both invalid are the same
      return true;
  }

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

  switch (m_opaque_sp->GetKind()) {
  case TypeSummaryImpl::Kind::eCallback:
    return llvm::dyn_cast<CXXFunctionSummaryFormat>(m_opaque_sp.get()) ==
           llvm::dyn_cast<CXXFunctionSummaryFormat>(rhs.m_opaque_sp.get());
  case TypeSummaryImpl::Kind::eScript:
    if (IsFunctionCode() != rhs.IsFunctionCode())
      return false;
    if (IsFunctionName() != rhs.IsFunctionName())
      return false;
    return GetOptions() == rhs.GetOptions();
  case TypeSummaryImpl::Kind::eSummaryString:
    if (IsSummaryString() != rhs.IsSummaryString())
      return false;
    return GetOptions() == rhs.GetOptions();
  case TypeSummaryImpl::Kind::eInternal:
    return (m_opaque_sp.get() == rhs.m_opaque_sp.get());
  }

  return false;
}

bool SBTypeSummary::operator!=(lldb::SBTypeSummary &rhs) {
  if (IsValid() == false)
    return !rhs.IsValid();
  return m_opaque_sp != rhs.m_opaque_sp;
}

lldb::TypeSummaryImplSP SBTypeSummary::GetSP() { return m_opaque_sp; }

void SBTypeSummary::SetSP(const lldb::TypeSummaryImplSP &typesummary_impl_sp) {
  m_opaque_sp = typesummary_impl_sp;
}

SBTypeSummary::SBTypeSummary(const lldb::TypeSummaryImplSP &typesummary_impl_sp)
    : m_opaque_sp(typesummary_impl_sp) {}

bool SBTypeSummary::CopyOnWrite_Impl() {
  if (!IsValid())
    return false;

  if (m_opaque_sp.unique())
    return true;

  TypeSummaryImplSP new_sp;

  if (CXXFunctionSummaryFormat *current_summary_ptr =
          llvm::dyn_cast<CXXFunctionSummaryFormat>(m_opaque_sp.get())) {
    new_sp = TypeSummaryImplSP(new CXXFunctionSummaryFormat(
        GetOptions(), current_summary_ptr->m_impl,
        current_summary_ptr->m_description.c_str()));
  } else if (ScriptSummaryFormat *current_summary_ptr =
                 llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) {
    new_sp = TypeSummaryImplSP(new ScriptSummaryFormat(
        GetOptions(), current_summary_ptr->GetFunctionName(),
        current_summary_ptr->GetPythonScript()));
  } else if (StringSummaryFormat *current_summary_ptr =
                 llvm::dyn_cast<StringSummaryFormat>(m_opaque_sp.get())) {
    new_sp = TypeSummaryImplSP(new StringSummaryFormat(
        GetOptions(), current_summary_ptr->GetSummaryString()));
  }

  SetSP(new_sp);

  return nullptr != new_sp.get();
}

bool SBTypeSummary::ChangeSummaryType(bool want_script) {
  if (!IsValid())
    return false;

  TypeSummaryImplSP new_sp;

  if (want_script ==
      (m_opaque_sp->GetKind() == TypeSummaryImpl::Kind::eScript)) {
    if (m_opaque_sp->GetKind() ==
            lldb_private::TypeSummaryImpl::Kind::eCallback &&
        !want_script)
      new_sp = TypeSummaryImplSP(new StringSummaryFormat(GetOptions(), ""));
    else
      return CopyOnWrite_Impl();
  }

  if (!new_sp) {
    if (want_script)
      new_sp = TypeSummaryImplSP(new ScriptSummaryFormat(GetOptions(), "", ""));
    else
      new_sp = TypeSummaryImplSP(new StringSummaryFormat(GetOptions(), ""));
  }

  SetSP(new_sp);

  return true;
}
