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

#include "JavaLanguageRuntime.h"

#include "lldb/Core/PluginManager.h"
#include "lldb/Symbol/JavaASTContext.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "llvm/ADT/StringRef.h"

using namespace lldb;
using namespace lldb_private;

JavaLanguageRuntime::JavaLanguageRuntime(Process *process) : LanguageRuntime(process)
{
}

LanguageRuntime *
JavaLanguageRuntime::CreateInstance(Process *process, lldb::LanguageType language)
{
    if (language == eLanguageTypeJava)
        return new JavaLanguageRuntime(process);
    return nullptr;
}

void
JavaLanguageRuntime::Initialize()
{
    PluginManager::RegisterPlugin(GetPluginNameStatic(), "Java language runtime", CreateInstance);
}

void
JavaLanguageRuntime::Terminate()
{
    PluginManager::UnregisterPlugin(CreateInstance);
}

lldb_private::ConstString
JavaLanguageRuntime::GetPluginNameStatic()
{
    static ConstString g_name("java");
    return g_name;
}

lldb_private::ConstString
JavaLanguageRuntime::GetPluginName()
{
    return GetPluginNameStatic();
}

uint32_t
JavaLanguageRuntime::GetPluginVersion()
{
    return 1;
}

bool
JavaLanguageRuntime::CouldHaveDynamicValue(ValueObject &in_value)
{
    return true;
}

static ConstString
GetDynamicTypeId(ExecutionContext *exe_ctx, Target *target, ValueObject &in_value)
{
    SymbolContext sc;
    TypeList class_types;
    llvm::DenseSet<SymbolFile *> searched_symbol_files;
    size_t num_matches = target->GetImages().FindTypes(sc, ConstString("Object"),
                                                       true, // name_is_fully_qualified
                                                       UINT32_MAX, searched_symbol_files, class_types);
    for (size_t i = 0; i < num_matches; ++i)
    {
        TypeSP type_sp = class_types.GetTypeAtIndex(i);
        CompilerType compiler_type = type_sp->GetFullCompilerType();

        if (compiler_type.GetMinimumLanguage() != eLanguageTypeJava ||
            compiler_type.GetTypeName() != ConstString("java::lang::Object"))
            continue;

        if (compiler_type.GetCompleteType() && compiler_type.IsCompleteType())
        {
            uint64_t type_id = JavaASTContext::CalculateDynamicTypeId(exe_ctx, compiler_type, in_value);
            if (type_id != UINT64_MAX)
            {
                char id[32];
                snprintf(id, sizeof(id), "0x%" PRIX64, type_id);
                return ConstString(id);
            }
        }
    }
    return ConstString();
}

bool
JavaLanguageRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
                                              TypeAndOrName &class_type_or_name, Address &dynamic_address,
                                              Value::ValueType &value_type)
{
    class_type_or_name.Clear();

    // null references don't have a dynamic type
    if (in_value.IsNilReference())
        return false;

    ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
    Target *target = exe_ctx.GetTargetPtr();
    if (!target)
        return false;

    ConstString linkage_name;
    CompilerType in_type = in_value.GetCompilerType();
    if (in_type.IsPossibleDynamicType(nullptr, false, false))
        linkage_name = GetDynamicTypeId(&exe_ctx, target, in_value);
    else
        linkage_name = JavaASTContext::GetLinkageName(in_type);

    if (!linkage_name)
        return false;

    class_type_or_name.SetName(in_type.GetNonReferenceType().GetTypeName());

    SymbolContext sc;
    TypeList class_types;
    llvm::DenseSet<SymbolFile *> searched_symbol_files;
    size_t num_matches = target->GetImages().FindTypes(sc, linkage_name,
                                                       true, // name_is_fully_qualified
                                                       UINT32_MAX, searched_symbol_files, class_types);

    for (size_t i = 0; i < num_matches; ++i)
    {
        TypeSP type_sp = class_types.GetTypeAtIndex(i);
        CompilerType compiler_type = type_sp->GetFullCompilerType();

        if (compiler_type.GetMinimumLanguage() != eLanguageTypeJava)
            continue;

        if (compiler_type.GetCompleteType() && compiler_type.IsCompleteType())
        {
            class_type_or_name.SetTypeSP(type_sp);

            Value &value = in_value.GetValue();
            value_type = value.GetValueType();
            dynamic_address.SetRawAddress(value.GetScalar().ULongLong(0));
            return true;
        }
    }
    return false;
}

TypeAndOrName
JavaLanguageRuntime::FixUpDynamicType(const TypeAndOrName &type_and_or_name, ValueObject &static_value)
{
    CompilerType static_type(static_value.GetCompilerType());

    TypeAndOrName ret(type_and_or_name);
    if (type_and_or_name.HasType())
    {
        CompilerType orig_type = type_and_or_name.GetCompilerType();
        if (static_type.IsReferenceType())
            ret.SetCompilerType(orig_type.GetLValueReferenceType());
    }
    return ret;
}
