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

#ifndef liblldb_ClangASTImporter_h_
#define liblldb_ClangASTImporter_h_

// C Includes
// C++ Includes
#include <map>
#include <memory>
#include <set>
#include <vector>

// Other libraries and framework includes
#include "clang/AST/ASTImporter.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/FileSystemOptions.h"

// Project includes
#include "lldb/Symbol/CompilerDeclContext.h"
#include "lldb/lldb-types.h"

#include "llvm/ADT/DenseMap.h"

namespace lldb_private {

class ClangASTMetrics {
public:
  static void DumpCounters(Log *log);
  static void ClearLocalCounters() { local_counters = {0, 0, 0, 0, 0, 0}; }

  static void RegisterVisibleQuery() {
    ++global_counters.m_visible_query_count;
    ++local_counters.m_visible_query_count;
  }

  static void RegisterLexicalQuery() {
    ++global_counters.m_lexical_query_count;
    ++local_counters.m_lexical_query_count;
  }

  static void RegisterLLDBImport() {
    ++global_counters.m_lldb_import_count;
    ++local_counters.m_lldb_import_count;
  }

  static void RegisterClangImport() {
    ++global_counters.m_clang_import_count;
    ++local_counters.m_clang_import_count;
  }

  static void RegisterDeclCompletion() {
    ++global_counters.m_decls_completed_count;
    ++local_counters.m_decls_completed_count;
  }

  static void RegisterRecordLayout() {
    ++global_counters.m_record_layout_count;
    ++local_counters.m_record_layout_count;
  }

private:
  struct Counters {
    uint64_t m_visible_query_count;
    uint64_t m_lexical_query_count;
    uint64_t m_lldb_import_count;
    uint64_t m_clang_import_count;
    uint64_t m_decls_completed_count;
    uint64_t m_record_layout_count;
  };

  static Counters global_counters;
  static Counters local_counters;

  static void DumpCounters(Log *log, Counters &counters);
};

class ClangASTImporter {
public:
  struct LayoutInfo {
    LayoutInfo()
        : bit_size(0), alignment(0), field_offsets(), base_offsets(),
          vbase_offsets() {}
    uint64_t bit_size;
    uint64_t alignment;
    llvm::DenseMap<const clang::FieldDecl *, uint64_t> field_offsets;
    llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> base_offsets;
    llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
        vbase_offsets;
  };

  ClangASTImporter() : m_file_manager(clang::FileSystemOptions()) {}

  clang::QualType CopyType(clang::ASTContext *dst_ctx,
                           clang::ASTContext *src_ctx, clang::QualType type);

  lldb::opaque_compiler_type_t CopyType(clang::ASTContext *dst_ctx,
                                        clang::ASTContext *src_ctx,
                                        lldb::opaque_compiler_type_t type);

  CompilerType CopyType(ClangASTContext &dst, const CompilerType &src_type);

  clang::Decl *CopyDecl(clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx,
                        clang::Decl *decl);

  lldb::opaque_compiler_type_t DeportType(clang::ASTContext *dst_ctx,
                                          clang::ASTContext *src_ctx,
                                          lldb::opaque_compiler_type_t type);

  clang::Decl *DeportDecl(clang::ASTContext *dst_ctx,
                          clang::ASTContext *src_ctx, clang::Decl *decl);

  void InsertRecordDecl(clang::RecordDecl *decl, const LayoutInfo &layout);

  bool LayoutRecordType(
      const clang::RecordDecl *record_decl, uint64_t &bit_size,
      uint64_t &alignment,
      llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
      llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
          &base_offsets,
      llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
          &vbase_offsets);

  bool CanImport(const CompilerType &type);

  bool Import(const CompilerType &type);

  bool CompleteType(const CompilerType &compiler_type);

  void CompleteDecl(clang::Decl *decl);

  bool CompleteTagDecl(clang::TagDecl *decl);

  bool CompleteTagDeclWithOrigin(clang::TagDecl *decl, clang::TagDecl *origin);

  bool CompleteObjCInterfaceDecl(clang::ObjCInterfaceDecl *interface_decl);

  bool CompleteAndFetchChildren(clang::QualType type);

  bool RequireCompleteType(clang::QualType type);

  bool ResolveDeclOrigin(const clang::Decl *decl, clang::Decl **original_decl,
                         clang::ASTContext **original_ctx) {
    DeclOrigin origin = GetDeclOrigin(decl);

    if (original_decl)
      *original_decl = origin.decl;

    if (original_ctx)
      *original_ctx = origin.ctx;

    return origin.Valid();
  }

  void SetDeclOrigin(const clang::Decl *decl, clang::Decl *original_decl);

  ClangASTMetadata *GetDeclMetadata(const clang::Decl *decl);

  //
  // Namespace maps
  //

  typedef std::vector<std::pair<lldb::ModuleSP, CompilerDeclContext>>
      NamespaceMap;
  typedef std::shared_ptr<NamespaceMap> NamespaceMapSP;

  void RegisterNamespaceMap(const clang::NamespaceDecl *decl,
                            NamespaceMapSP &namespace_map);

  NamespaceMapSP GetNamespaceMap(const clang::NamespaceDecl *decl);

  void BuildNamespaceMap(const clang::NamespaceDecl *decl);

  //
  // Completers for maps
  //

  class MapCompleter {
  public:
    virtual ~MapCompleter();

    virtual void CompleteNamespaceMap(NamespaceMapSP &namespace_map,
                                      const ConstString &name,
                                      NamespaceMapSP &parent_map) const = 0;
  };

  void InstallMapCompleter(clang::ASTContext *dst_ctx,
                           MapCompleter &completer) {
    ASTContextMetadataSP context_md;
    ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);

    if (context_md_iter == m_metadata_map.end()) {
      context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
      m_metadata_map[dst_ctx] = context_md;
    } else {
      context_md = context_md_iter->second;
    }

    context_md->m_map_completer = &completer;
  }

  void ForgetDestination(clang::ASTContext *dst_ctx);
  void ForgetSource(clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx);

private:
  struct DeclOrigin {
    DeclOrigin() : ctx(nullptr), decl(nullptr) {}

    DeclOrigin(clang::ASTContext *_ctx, clang::Decl *_decl)
        : ctx(_ctx), decl(_decl) {}

    DeclOrigin(const DeclOrigin &rhs) {
      ctx = rhs.ctx;
      decl = rhs.decl;
    }

    void operator=(const DeclOrigin &rhs) {
      ctx = rhs.ctx;
      decl = rhs.decl;
    }

    bool Valid() { return (ctx != nullptr || decl != nullptr); }

    clang::ASTContext *ctx;
    clang::Decl *decl;
  };

  typedef std::map<const clang::Decl *, DeclOrigin> OriginMap;

  class Minion : public clang::ASTImporter {
  public:
    Minion(ClangASTImporter &master, clang::ASTContext *target_ctx,
           clang::ASTContext *source_ctx)
        : clang::ASTImporter(*target_ctx, master.m_file_manager, *source_ctx,
                             master.m_file_manager, true /*minimal*/),
          m_decls_to_deport(nullptr), m_decls_already_deported(nullptr),
          m_master(master), m_source_ctx(source_ctx) {}

    // A call to "InitDeportWorkQueues" puts the minion into deport mode.
    // In deport mode, every copied Decl that could require completion is
    // recorded and placed into the decls_to_deport set.
    //
    // A call to "ExecuteDeportWorkQueues" completes all the Decls that
    // are in decls_to_deport, adding any Decls it sees along the way that it
    // hasn't already deported.  It proceeds until decls_to_deport is empty.
    //
    // These calls must be paired.  Leaving a minion in deport mode or trying
    // to start deport minion with a new pair of queues will result in an
    // assertion failure.

    void
    InitDeportWorkQueues(std::set<clang::NamedDecl *> *decls_to_deport,
                         std::set<clang::NamedDecl *> *decls_already_deported);
    void ExecuteDeportWorkQueues();

    void ImportDefinitionTo(clang::Decl *to, clang::Decl *from);

    clang::Decl *Imported(clang::Decl *from, clang::Decl *to) override;

    clang::Decl *GetOriginalDecl(clang::Decl *To) override;

    std::set<clang::NamedDecl *> *m_decls_to_deport;
    std::set<clang::NamedDecl *> *m_decls_already_deported;
    ClangASTImporter &m_master;
    clang::ASTContext *m_source_ctx;
  };

  typedef std::shared_ptr<Minion> MinionSP;
  typedef std::map<clang::ASTContext *, MinionSP> MinionMap;
  typedef std::map<const clang::NamespaceDecl *, NamespaceMapSP>
      NamespaceMetaMap;

  struct ASTContextMetadata {
    ASTContextMetadata(clang::ASTContext *dst_ctx)
        : m_dst_ctx(dst_ctx), m_minions(), m_origins(), m_namespace_maps(),
          m_map_completer(nullptr) {}

    clang::ASTContext *m_dst_ctx;
    MinionMap m_minions;
    OriginMap m_origins;

    NamespaceMetaMap m_namespace_maps;
    MapCompleter *m_map_completer;
  };

  typedef std::shared_ptr<ASTContextMetadata> ASTContextMetadataSP;
  typedef std::map<const clang::ASTContext *, ASTContextMetadataSP>
      ContextMetadataMap;

  ContextMetadataMap m_metadata_map;

  ASTContextMetadataSP GetContextMetadata(clang::ASTContext *dst_ctx) {
    ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);

    if (context_md_iter == m_metadata_map.end()) {
      ASTContextMetadataSP context_md =
          ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
      m_metadata_map[dst_ctx] = context_md;
      return context_md;
    } else {
      return context_md_iter->second;
    }
  }

  ASTContextMetadataSP MaybeGetContextMetadata(clang::ASTContext *dst_ctx) {
    ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);

    if (context_md_iter != m_metadata_map.end())
      return context_md_iter->second;
    else
      return ASTContextMetadataSP();
  }

  MinionSP GetMinion(clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx) {
    ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx);

    MinionMap &minions = context_md->m_minions;
    MinionMap::iterator minion_iter = minions.find(src_ctx);

    if (minion_iter == minions.end()) {
      MinionSP minion = MinionSP(new Minion(*this, dst_ctx, src_ctx));
      minions[src_ctx] = minion;
      return minion;
    } else {
      return minion_iter->second;
    }
  }

  DeclOrigin GetDeclOrigin(const clang::Decl *decl);

  clang::FileManager m_file_manager;
  typedef llvm::DenseMap<const clang::RecordDecl *, LayoutInfo>
      RecordDeclToLayoutMap;

  RecordDeclToLayoutMap m_record_decl_to_layout_map;
};

} // namespace lldb_private

#endif // liblldb_ClangASTImporter_h_
