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

#include "lldb/Symbol/OCamlASTContext.h"
#include "lldb/Core/DumpDataExtractor.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/Log.h"

#include "Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h"

using namespace lldb;
using namespace lldb_private;

namespace lldb_private {
class OCamlASTContext::OCamlType {
public:
  enum LLVMCastKind {
    eKindPrimitive,
    eKindObject,
    eKindReference,
    eKindArray,
    kNumKinds
  };

  OCamlType(LLVMCastKind kind) : m_kind(kind) {}

  virtual ~OCamlType() = default;

  virtual ConstString GetName() = 0;

  virtual void Dump(Stream *s) = 0;

  virtual bool IsCompleteType() = 0;

  LLVMCastKind getKind() const { return m_kind; }

private:
  LLVMCastKind m_kind;
};

} // end of namespace lldb_private

namespace {

class OCamlPrimitiveType : public OCamlASTContext::OCamlType {
public:
  enum TypeKind {
    eTypeInt,
  };

  OCamlPrimitiveType(TypeKind type_kind, uint32_t byte_size)
      : OCamlType(OCamlType::eKindPrimitive), m_type_kind(type_kind),
        m_type(ConstString()), m_byte_size(byte_size) {}

  OCamlPrimitiveType(TypeKind type_kind, ConstString s, uint32_t byte_size)
      : OCamlType(OCamlType::eKindPrimitive), m_type_kind(type_kind), m_type(s),
        m_byte_size(byte_size) {}

  ConstString GetName() override {
    switch (m_type_kind) {
    case eTypeInt:
      return m_type;
    }
    return ConstString();
  }

  TypeKind GetTypeKind() { return m_type_kind; }

  void Dump(Stream *s) override { s->Printf("%s\n", GetName().GetCString()); }

  bool IsCompleteType() override { return true; }

  static bool classof(const OCamlType *ot) {
    return ot->getKind() == OCamlType::eKindPrimitive;
  }

  uint64_t GetByteSize() const { return m_byte_size; }

private:
  const TypeKind m_type_kind;
  const ConstString m_type;
  uint64_t m_byte_size;
};
}

OCamlASTContext::OCamlASTContext()
    : TypeSystem(eKindOCaml), m_pointer_byte_size(0) {}

OCamlASTContext::~OCamlASTContext() {}

ConstString OCamlASTContext::GetPluginNameStatic() {
  return ConstString("ocaml");
}

ConstString OCamlASTContext::GetPluginName() {
  return OCamlASTContext::GetPluginNameStatic();
}

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

lldb::TypeSystemSP OCamlASTContext::CreateInstance(lldb::LanguageType language,
                                                   Module *module,
                                                   Target *target) {
  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE));

  if (language == lldb::eLanguageTypeOCaml) {
    std::shared_ptr<OCamlASTContext> ocaml_ast_sp;
    ArchSpec arch;

    if (module) {
      arch = module->GetArchitecture();

      ObjectFile *objfile = module->GetObjectFile();
      ArchSpec object_arch;

      if (!objfile || !objfile->GetArchitecture(object_arch))
        return lldb::TypeSystemSP();

      ocaml_ast_sp = std::shared_ptr<OCamlASTContext>(new OCamlASTContext);

      if (log) {
        log->Printf(
            "((Module*)%p) [%s]->GetOCamlASTContext() = %p", (void *)module,
            module->GetFileSpec().GetFilename().AsCString("<anonymous>"),
            (void *)ocaml_ast_sp.get());
      }

    } else if (target) {
      arch = target->GetArchitecture();
      ocaml_ast_sp = std::shared_ptr<OCamlASTContextForExpr>(
          new OCamlASTContextForExpr(target->shared_from_this()));

      if (log) {
        log->Printf("((Target*)%p)->GetOCamlASTContext() = %p", (void *)target,
                    (void *)ocaml_ast_sp.get());
      }
    }

    if (arch.IsValid()) {
      ocaml_ast_sp->SetAddressByteSize(arch.GetAddressByteSize());
      return ocaml_ast_sp;
    }
  }

  return lldb::TypeSystemSP();
}

void OCamlASTContext::EnumerateSupportedLanguages(
    std::set<lldb::LanguageType> &languages_for_types,
    std::set<lldb::LanguageType> &languages_for_expressions) {
  static std::vector<lldb::LanguageType> s_supported_languages_for_types(
      {lldb::eLanguageTypeOCaml});
  static std::vector<lldb::LanguageType> s_supported_languages_for_expressions(
      {});

  languages_for_types.insert(s_supported_languages_for_types.begin(),
                             s_supported_languages_for_types.end());
  languages_for_expressions.insert(
      s_supported_languages_for_expressions.begin(),
      s_supported_languages_for_expressions.end());
}

void OCamlASTContext::Initialize() {
  PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                "OCaml AST context plug-in", CreateInstance,
                                EnumerateSupportedLanguages);
}

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

DWARFASTParser *OCamlASTContext::GetDWARFParser() {
  if (!m_dwarf_ast_parser_ap) {
    m_dwarf_ast_parser_ap.reset(new DWARFASTParserOCaml(*this));
  }

  return m_dwarf_ast_parser_ap.get();
}

bool OCamlASTContext::IsArrayType(lldb::opaque_compiler_type_t type,
                                  CompilerType *element_type, uint64_t *size,
                                  bool *is_incomplete) {
  return false;
}

bool OCamlASTContext::IsVectorType(lldb::opaque_compiler_type_t type,
                                   CompilerType *element_type, uint64_t *size) {
  return false;
}

bool OCamlASTContext::IsAggregateType(lldb::opaque_compiler_type_t type) {
  return false;
}

bool OCamlASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type) {
  return false;
}

bool OCamlASTContext::IsCharType(lldb::opaque_compiler_type_t type) {
  return false;
}

bool OCamlASTContext::IsCompleteType(lldb::opaque_compiler_type_t type) {
  return static_cast<OCamlPrimitiveType *>(type)->IsCompleteType();
}

bool OCamlASTContext::IsConst(lldb::opaque_compiler_type_t type) {
  return false;
}

bool OCamlASTContext::IsCStringType(lldb::opaque_compiler_type_t type,
                                    uint32_t &length) {
  return false;
}

bool OCamlASTContext::IsDefined(lldb::opaque_compiler_type_t type) {
  return type != nullptr;
}

bool OCamlASTContext::IsFloatingPointType(lldb::opaque_compiler_type_t type,
                                          uint32_t &count, bool &is_complex) {
  return false;
}

bool OCamlASTContext::IsFunctionType(lldb::opaque_compiler_type_t type,
                                     bool *is_variadic_ptr) {
  return false;
}

uint32_t
OCamlASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
                                        CompilerType *base_type_ptr) {
  return false;
}

size_t OCamlASTContext::GetNumberOfFunctionArguments(
    lldb::opaque_compiler_type_t type) {
  return 0;
}

CompilerType
OCamlASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type,
                                            const size_t index) {
  return CompilerType();
}

bool OCamlASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type) {
  return IsFunctionType(type);
}

bool OCamlASTContext::IsBlockPointerType(
    lldb::opaque_compiler_type_t type,
    CompilerType *function_pointer_type_ptr) {
  return false;
}

bool OCamlASTContext::IsIntegerType(lldb::opaque_compiler_type_t type,
                                    bool &is_signed) {
  if (OCamlPrimitiveType *ptype =
          llvm::dyn_cast<OCamlPrimitiveType>(static_cast<OCamlType *>(type))) {
    switch (ptype->GetTypeKind()) {
    case OCamlPrimitiveType::eTypeInt:
      is_signed = true;
      return true;
    }
  }

  is_signed = false;
  return false;
}

bool OCamlASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type) {
  return false;
}

bool OCamlASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
                                            CompilerType *target_type,
                                            bool check_cplusplus,
                                            bool check_objc) {
  return false;
}

bool OCamlASTContext::IsRuntimeGeneratedType(
    lldb::opaque_compiler_type_t type) {
  return false;
}

bool OCamlASTContext::IsPointerType(lldb::opaque_compiler_type_t type,
                                    CompilerType *pointee_type) {
  if (pointee_type)
    pointee_type->Clear();
  return false;
}

bool OCamlASTContext::IsPointerOrReferenceType(
    lldb::opaque_compiler_type_t type, CompilerType *pointee_type) {
  return IsPointerType(type, pointee_type);
}

bool OCamlASTContext::IsReferenceType(lldb::opaque_compiler_type_t type,
                                      CompilerType *pointee_type,
                                      bool *is_rvalue) {
  return false;
}

bool OCamlASTContext::IsScalarType(lldb::opaque_compiler_type_t type) {
  return llvm::isa<OCamlPrimitiveType>(static_cast<OCamlType *>(type));
}

bool OCamlASTContext::IsTypedefType(lldb::opaque_compiler_type_t type) {
  return false;
}

bool OCamlASTContext::IsVoidType(lldb::opaque_compiler_type_t type) {
  return false;
}

bool OCamlASTContext::SupportsLanguage(lldb::LanguageType language) {
  return language == lldb::eLanguageTypeOCaml;
}

bool OCamlASTContext::GetCompleteType(lldb::opaque_compiler_type_t type) {
  if (IsCompleteType(type))
    return true;

  return false;
}

uint32_t OCamlASTContext::GetPointerByteSize() { return m_pointer_byte_size; }

ConstString OCamlASTContext::GetTypeName(lldb::opaque_compiler_type_t type) {
  if (type)
    return static_cast<OCamlPrimitiveType *>(type)->GetName();

  return ConstString();
}

uint32_t
OCamlASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
                             CompilerType *pointee_or_element_compiler_type) {
  if (pointee_or_element_compiler_type)
    pointee_or_element_compiler_type->Clear();
  if (!type)
    return 0;

  if (OCamlPrimitiveType *ptype =
          llvm::dyn_cast<OCamlPrimitiveType>(static_cast<OCamlType *>(type))) {
    switch (ptype->GetTypeKind()) {
    case OCamlPrimitiveType::eTypeInt:
      return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar | eTypeIsInteger |
             eTypeIsSigned;
    }
  }

  return 0;
}

lldb::TypeClass
OCamlASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) {
  if (llvm::isa<OCamlPrimitiveType>(static_cast<OCamlType *>(type)))
    return eTypeClassBuiltin;

  return lldb::eTypeClassInvalid;
}

lldb::BasicType
OCamlASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) {
  return lldb::eBasicTypeInvalid;
}

lldb::LanguageType
OCamlASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type) {
  return lldb::eLanguageTypeOCaml;
}

unsigned OCamlASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type) {
  return 0;
}

//----------------------------------------------------------------------
// Creating related types
//----------------------------------------------------------------------

CompilerType
OCamlASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type,
                                     uint64_t *stride) {
  return CompilerType();
}

CompilerType
OCamlASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type) {
  return CompilerType(this, type);
}

CompilerType
OCamlASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) {
  return CompilerType(this, type);
}

int OCamlASTContext::GetFunctionArgumentCount(
    lldb::opaque_compiler_type_t type) {
  return GetNumberOfFunctionArguments(type);
}

CompilerType OCamlASTContext::GetFunctionArgumentTypeAtIndex(
    lldb::opaque_compiler_type_t type, size_t idx) {
  return GetFunctionArgumentAtIndex(type, idx);
}

CompilerType
OCamlASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type) {
  return CompilerType();
}

size_t
OCamlASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) {
  return 0;
}

TypeMemberFunctionImpl
OCamlASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type,
                                          size_t idx) {
  return TypeMemberFunctionImpl();
}

CompilerType
OCamlASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type) {
  return CompilerType(this, type);
}

CompilerType
OCamlASTContext::GetPointeeType(lldb::opaque_compiler_type_t type) {
  return CompilerType();
}

CompilerType
OCamlASTContext::GetPointerType(lldb::opaque_compiler_type_t type) {
  return CompilerType();
}

CompilerType
OCamlASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type) {
  return CompilerType();
}

CompilerType OCamlASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type) {
  return CompilerType();
}

CompilerType
OCamlASTContext::GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding,
                                                     size_t bit_size) {
  return CompilerType();
}

uint64_t OCamlASTContext::GetBitSize(lldb::opaque_compiler_type_t type,
                                     ExecutionContextScope *exe_scope) {
  if (OCamlPrimitiveType *ptype =
          llvm::dyn_cast<OCamlPrimitiveType>(static_cast<OCamlType *>(type))) {
    switch (ptype->GetTypeKind()) {
    case OCamlPrimitiveType::eTypeInt:
      return ptype->GetByteSize() * 8;
    }
  }
  return 0;
}

lldb::Encoding OCamlASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
                                            uint64_t &count) {
  count = 1;
  bool is_signed;
  if (IsIntegerType(type, is_signed))
    return is_signed ? lldb::eEncodingSint : lldb::eEncodingUint;
  bool is_complex;
  uint32_t complex_count;
  if (IsFloatingPointType(type, complex_count, is_complex)) {
    count = complex_count;
    return lldb::eEncodingIEEE754;
  }
  if (IsPointerType(type))
    return lldb::eEncodingUint;
  return lldb::eEncodingInvalid;
}

lldb::Format OCamlASTContext::GetFormat(lldb::opaque_compiler_type_t type) {
  if (!type)
    return lldb::eFormatDefault;
  return lldb::eFormatBytes;
}

size_t OCamlASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type) {
  return 0;
}

uint32_t OCamlASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
                                         bool omit_empty_base_classes) {
  if (!type || !GetCompleteType(type))
    return 0;

  return GetNumFields(type);
}

uint32_t OCamlASTContext::GetNumFields(lldb::opaque_compiler_type_t type) {
  if (!type || !GetCompleteType(type))
    return 0;
  return 0;
}

CompilerType OCamlASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type,
                                              size_t idx, std::string &name,
                                              uint64_t *bit_offset_ptr,
                                              uint32_t *bitfield_bit_size_ptr,
                                              bool *is_bitfield_ptr) {
  if (bit_offset_ptr)
    *bit_offset_ptr = 0;
  if (bitfield_bit_size_ptr)
    *bitfield_bit_size_ptr = 0;
  if (is_bitfield_ptr)
    *is_bitfield_ptr = false;

  if (!type || !GetCompleteType(type))
    return CompilerType();

  return CompilerType();
}

CompilerType OCamlASTContext::GetChildCompilerTypeAtIndex(
    lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
    bool transparent_pointers, bool omit_empty_base_classes,
    bool ignore_array_bounds, std::string &child_name,
    uint32_t &child_byte_size, int32_t &child_byte_offset,
    uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
    bool &child_is_base_class, bool &child_is_deref_of_parent,
    ValueObject *valobj, uint64_t &language_flags) {
  child_name.clear();
  child_byte_size = 0;
  child_byte_offset = 0;
  child_bitfield_bit_size = 0;
  child_bitfield_bit_offset = 0;
  child_is_base_class = false;
  child_is_deref_of_parent = false;
  language_flags = 0;

  if (!type || !GetCompleteType(type))
    return CompilerType();

  return CompilerType();
}

uint32_t
OCamlASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
                                         const char *name,
                                         bool omit_empty_base_classes) {
  if (!type || !GetCompleteType(type))
    return UINT_MAX;

  return UINT_MAX;
}

size_t OCamlASTContext::GetIndexOfChildMemberWithName(
    lldb::opaque_compiler_type_t type, const char *name,
    bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) {
  uint32_t index = GetIndexOfChildWithName(type, name, omit_empty_base_classes);
  if (index == UINT_MAX)
    return 0;
  child_indexes.push_back(index);
  return 1;
}

size_t
OCamlASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type,
                                           const char *s, uint8_t *dst,
                                           size_t dst_size) {
  assert(false);
  return 0;
}
//----------------------------------------------------------------------
// Dumping types
//----------------------------------------------------------------------

void OCamlASTContext::DumpValue(
    lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s,
    lldb::Format format, const DataExtractor &data,
    lldb::offset_t data_byte_offset, size_t data_byte_size,
    uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types,
    bool show_summary, bool verbose, uint32_t depth) {
  if (!type) {
    s->Printf("no type\n");
    return;
  }

  s->Printf("no value\n");

  if (show_summary)
    DumpSummary(type, exe_ctx, s, data, data_byte_offset, data_byte_size);
}

bool OCamlASTContext::DumpTypeValue(
    lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format,
    const DataExtractor &data, lldb::offset_t byte_offset, size_t byte_size,
    uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
    ExecutionContextScope *exe_scope) {
  if (!type) {
    s->Printf("no type value\n");
    return false;
  }

  if (IsScalarType(type)) {
    return DumpDataExtractor(data, s, byte_offset, format, byte_size, 1,
                             SIZE_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size,
                             bitfield_bit_offset, exe_scope);
  }

  return false;
}

void OCamlASTContext::DumpSummary(lldb::opaque_compiler_type_t type,
                                  ExecutionContext *exe_ctx, Stream *s,
                                  const DataExtractor &data,
                                  lldb::offset_t data_offset,
                                  size_t data_byte_size) {
  s->Printf("no summary\n");
}

void OCamlASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type) {
  StreamFile s(stdout, false);
  DumpTypeDescription(type, &s);
}

void OCamlASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type,
                                          Stream *s) {
  static_cast<OCamlType *>(type)->Dump(s);
}

CompilerType OCamlASTContext::CreateBaseType(const ConstString &name,
                                             uint64_t byte_size) {
  if (m_base_type_map.empty()) {
    OCamlPrimitiveType *type = new OCamlPrimitiveType(
        OCamlPrimitiveType::eTypeInt, ConstString("ocaml_int"), byte_size);
    m_base_type_map.emplace(type->GetName(),
                            std::unique_ptr<OCamlASTContext::OCamlType>(type));
  }

  auto it = m_base_type_map.find(name);
  if (it == m_base_type_map.end()) {
    OCamlPrimitiveType *type =
        new OCamlPrimitiveType(OCamlPrimitiveType::eTypeInt, name, byte_size);
    it = m_base_type_map
             .emplace(name, std::unique_ptr<OCamlASTContext::OCamlType>(type))
             .first;
  }

  return CompilerType(this, it->second.get());
}
