//===-- JavaFormatterFunctions.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
// Project includes
#include "JavaFormatterFunctions.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/DataFormatters/StringPrinter.h"
#include "lldb/Symbol/JavaASTContext.h"

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

namespace {

class JavaArraySyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
  JavaArraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
      : SyntheticChildrenFrontEnd(*valobj_sp) {
    if (valobj_sp)
      Update();
  }

  size_t CalculateNumChildren() override {
    ValueObjectSP valobj = GetDereferencedValueObject();
    if (!valobj)
      return 0;

    CompilerType type = valobj->GetCompilerType();
    uint32_t size = JavaASTContext::CalculateArraySize(type, *valobj);
    if (size == UINT32_MAX)
      return 0;
    return size;
  }

  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
    ValueObjectSP valobj = GetDereferencedValueObject();
    if (!valobj)
      return nullptr;

    ProcessSP process_sp = valobj->GetProcessSP();
    if (!process_sp)
      return nullptr;

    CompilerType type = valobj->GetCompilerType();
    CompilerType element_type = type.GetArrayElementType();
    lldb::addr_t address =
        valobj->GetAddressOf() +
        JavaASTContext::CalculateArrayElementOffset(type, idx);

    Error error;
    size_t byte_size = element_type.GetByteSize(nullptr);
    DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
    size_t bytes_read = process_sp->ReadMemory(address, buffer_sp->GetBytes(),
                                               byte_size, error);
    if (error.Fail() || byte_size != bytes_read)
      return nullptr;

    StreamString name;
    name.Printf("[%" PRIu64 "]", (uint64_t)idx);
    DataExtractor data(buffer_sp, process_sp->GetByteOrder(),
                       process_sp->GetAddressByteSize());
    return CreateValueObjectFromData(
        name.GetData(), data, valobj->GetExecutionContextRef(), element_type);
  }

  bool Update() override { return false; }

  bool MightHaveChildren() override { return true; }

  size_t GetIndexOfChildWithName(const ConstString &name) override {
    return ExtractIndexFromString(name.GetCString());
  }

private:
  ValueObjectSP GetDereferencedValueObject() {
    if (!m_backend.IsPointerOrReferenceType())
      return m_backend.GetSP();

    Error error;
    return m_backend.Dereference(error);
  }
};

} // end of anonymous namespace

bool lldb_private::formatters::JavaStringSummaryProvider(
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &opts) {
  if (valobj.IsPointerOrReferenceType()) {
    Error error;
    ValueObjectSP deref = valobj.Dereference(error);
    if (error.Fail())
      return false;
    return JavaStringSummaryProvider(*deref, stream, opts);
  }

  ProcessSP process_sp = valobj.GetProcessSP();
  if (!process_sp)
    return false;

  ConstString data_name("value");
  ConstString length_name("count");

  ValueObjectSP length_sp = valobj.GetChildMemberWithName(length_name, true);
  ValueObjectSP data_sp = valobj.GetChildMemberWithName(data_name, true);
  if (!data_sp || !length_sp)
    return false;

  bool success = false;
  uint64_t length = length_sp->GetValueAsUnsigned(0, &success);
  if (!success)
    return false;

  if (length == 0) {
    stream.Printf("\"\"");
    return true;
  }
  lldb::addr_t valobj_addr = data_sp->GetAddressOf();

  StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
  options.SetLocation(valobj_addr);
  options.SetProcessSP(process_sp);
  options.SetStream(&stream);
  options.SetSourceSize(length);
  options.SetNeedsZeroTermination(false);
  options.SetLanguage(eLanguageTypeJava);

  if (StringPrinter::ReadStringAndDumpToStream<
          StringPrinter::StringElementType::UTF16>(options))
    return true;

  stream.Printf("Summary Unavailable");
  return true;
}

bool lldb_private::formatters::JavaArraySummaryProvider(
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
  if (valobj.IsPointerOrReferenceType()) {
    Error error;
    ValueObjectSP deref = valobj.Dereference(error);
    if (error.Fail())
      return false;
    return JavaArraySummaryProvider(*deref, stream, options);
  }

  CompilerType type = valobj.GetCompilerType();
  uint32_t size = JavaASTContext::CalculateArraySize(type, valobj);
  if (size == UINT32_MAX)
    return false;
  stream.Printf("[%u]{...}", size);
  return true;
}

SyntheticChildrenFrontEnd *
lldb_private::formatters::JavaArraySyntheticFrontEndCreator(
    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
  return valobj_sp ? new JavaArraySyntheticFrontEnd(valobj_sp) : nullptr;
}
