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