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

// C Includes
// C++ Includes
// Other libraries and framework includes
#include "clang/AST/DeclCXX.h"

// Project includes
#include "Cocoa.h"

#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/Host/Endian.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Target.h"

#include "lldb/Utility/ProcessStructReader.h"

#include "Plugins/Language/ObjC/NSString.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;

static lldb::addr_t DerefToNSErrorPointer(ValueObject &valobj) {
  CompilerType valobj_type(valobj.GetCompilerType());
  Flags type_flags(valobj_type.GetTypeInfo());
  if (type_flags.AllClear(eTypeHasValue)) {
    if (valobj.IsBaseClass() && valobj.GetParent())
      return valobj.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
  } else {
    lldb::addr_t ptr_value = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
    if (type_flags.AllSet(eTypeIsPointer)) {
      CompilerType pointee_type(valobj_type.GetPointeeType());
      Flags pointee_flags(pointee_type.GetTypeInfo());
      if (pointee_flags.AllSet(eTypeIsPointer)) {
        if (ProcessSP process_sp = valobj.GetProcessSP()) {
          Error error;
          ptr_value = process_sp->ReadPointerFromMemory(ptr_value, error);
        }
      }
    }
    return ptr_value;
  }

  return LLDB_INVALID_ADDRESS;
}

bool lldb_private::formatters::NSError_SummaryProvider(
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
  ProcessSP process_sp(valobj.GetProcessSP());
  if (!process_sp)
    return false;

  lldb::addr_t ptr_value = DerefToNSErrorPointer(valobj);
  if (ptr_value == LLDB_INVALID_ADDRESS)
    return false;

  size_t ptr_size = process_sp->GetAddressByteSize();
  lldb::addr_t code_location = ptr_value + 2 * ptr_size;
  lldb::addr_t domain_location = ptr_value + 3 * ptr_size;

  Error error;
  uint64_t code = process_sp->ReadUnsignedIntegerFromMemory(code_location,
                                                            ptr_size, 0, error);
  if (error.Fail())
    return false;

  lldb::addr_t domain_str_value =
      process_sp->ReadPointerFromMemory(domain_location, error);
  if (error.Fail() || domain_str_value == LLDB_INVALID_ADDRESS)
    return false;

  if (!domain_str_value) {
    stream.Printf("domain: nil - code: %" PRIu64, code);
    return true;
  }

  InferiorSizedWord isw(domain_str_value, *process_sp);

  ValueObjectSP domain_str_sp = ValueObject::CreateValueObjectFromData(
      "domain_str", isw.GetAsData(process_sp->GetByteOrder()),
      valobj.GetExecutionContextRef(), process_sp->GetTarget()
                                           .GetScratchClangASTContext()
                                           ->GetBasicType(lldb::eBasicTypeVoid)
                                           .GetPointerType());

  if (!domain_str_sp)
    return false;

  StreamString domain_str_summary;
  if (NSStringSummaryProvider(*domain_str_sp, domain_str_summary, options) &&
      !domain_str_summary.Empty()) {
    stream.Printf("domain: %s - code: %" PRIu64, domain_str_summary.GetData(),
                  code);
    return true;
  } else {
    stream.Printf("domain: nil - code: %" PRIu64, code);
    return true;
  }
}

class NSErrorSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
  NSErrorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
      : SyntheticChildrenFrontEnd(*valobj_sp) {}

  ~NSErrorSyntheticFrontEnd() override = default;
  // no need to delete m_child_ptr - it's kept alive by the cluster manager on
  // our behalf

  size_t CalculateNumChildren() override {
    if (m_child_ptr)
      return 1;
    if (m_child_sp)
      return 1;
    return 0;
  }

  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
    if (idx != 0)
      return lldb::ValueObjectSP();

    if (m_child_ptr)
      return m_child_ptr->GetSP();
    return m_child_sp;
  }

  bool Update() override {
    m_child_ptr = nullptr;
    m_child_sp.reset();

    ProcessSP process_sp(m_backend.GetProcessSP());
    if (!process_sp)
      return false;

    lldb::addr_t userinfo_location = DerefToNSErrorPointer(m_backend);
    if (userinfo_location == LLDB_INVALID_ADDRESS)
      return false;

    size_t ptr_size = process_sp->GetAddressByteSize();

    userinfo_location += 4 * ptr_size;
    Error error;
    lldb::addr_t userinfo =
        process_sp->ReadPointerFromMemory(userinfo_location, error);
    if (userinfo == LLDB_INVALID_ADDRESS || error.Fail())
      return false;
    InferiorSizedWord isw(userinfo, *process_sp);
    m_child_sp = CreateValueObjectFromData(
        "_userInfo", isw.GetAsData(process_sp->GetByteOrder()),
        m_backend.GetExecutionContextRef(),
        process_sp->GetTarget().GetScratchClangASTContext()->GetBasicType(
            lldb::eBasicTypeObjCID));
    return false;
  }

  bool MightHaveChildren() override { return true; }

  size_t GetIndexOfChildWithName(const ConstString &name) override {
    static ConstString g___userInfo("_userInfo");
    if (name == g___userInfo)
      return 0;
    return UINT32_MAX;
  }

private:
  // the child here can be "real" (i.e. an actual child of the root) or
  // synthetized from raw memory
  // if the former, I need to store a plain pointer to it - or else a loop of
  // references will cause this entire hierarchy of values to leak
  // if the latter, then I need to store a SharedPointer to it - so that it only
  // goes away when everyone else in the cluster goes away
  // oh joy!
  ValueObject *m_child_ptr;
  ValueObjectSP m_child_sp;
};

SyntheticChildrenFrontEnd *
lldb_private::formatters::NSErrorSyntheticFrontEndCreator(
    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
  lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
  if (!process_sp)
    return nullptr;
  ObjCLanguageRuntime *runtime =
      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
          lldb::eLanguageTypeObjC);
  if (!runtime)
    return nullptr;

  ObjCLanguageRuntime::ClassDescriptorSP descriptor(
      runtime->GetClassDescriptor(*valobj_sp.get()));

  if (!descriptor.get() || !descriptor->IsValid())
    return nullptr;

  const char *class_name = descriptor->GetClassName().GetCString();

  if (!class_name || !*class_name)
    return nullptr;

  if (!strcmp(class_name, "NSError"))
    return (new NSErrorSyntheticFrontEnd(valobj_sp));
  else if (!strcmp(class_name, "__NSCFError"))
    return (new NSErrorSyntheticFrontEnd(valobj_sp));

  return nullptr;
}
