//===-- 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;
}
