//===-- 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_

#include <map>
#include <set>

#include "lldb/lldb-types.h"
#include "clang/AST/ASTImporter.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/FileSystemOptions.h"
#include "lldb/Symbol/ClangNamespaceDecl.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:
    ClangASTImporter () :
        m_file_manager(clang::FileSystemOptions())
    {
    }
    
    clang::QualType
    CopyType (clang::ASTContext *dst_ctx,
              clang::ASTContext *src_ctx,
              clang::QualType type);
    
    lldb::clang_type_t
    CopyType (clang::ASTContext *dst_ctx,
              clang::ASTContext *src_ctx,
              lldb::clang_type_t type);
    
    clang::Decl *
    CopyDecl (clang::ASTContext *dst_ctx,
              clang::ASTContext *src_ctx,
              clang::Decl *decl);
    
    lldb::clang_type_t
    DeportType (clang::ASTContext *dst_ctx,
                clang::ASTContext *src_ctx,
                lldb::clang_type_t type);
    
    clang::Decl *
    DeportDecl (clang::ASTContext *dst_ctx,
                clang::ASTContext *src_ctx,
                clang::Decl *decl);
    
    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
    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, ClangNamespaceDecl> > 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);
    
    //
    // Comleters 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(NULL),
            decl(NULL)
        {
        }
        
        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 != NULL || decl != NULL);
        }
        
        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(NULL),
            m_decls_already_deported(NULL),
            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);
        
        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 (NULL)
        {
        }
        
        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;
};
    
}

#endif
