//===-- ObjCLanguageRuntime.cpp ---------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "clang/AST/Type.h"

#include "lldb/Core/Log.h"
#include "lldb/Core/MappedHash.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Timer.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Target.h"

#include "llvm/ADT/StringRef.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
ObjCLanguageRuntime::~ObjCLanguageRuntime()
{
}

ObjCLanguageRuntime::ObjCLanguageRuntime (Process *process) :
    LanguageRuntime (process),
    m_has_new_literals_and_indexing (eLazyBoolCalculate),
    m_isa_to_descriptor(),
    m_isa_to_descriptor_stop_id (UINT32_MAX)
{

}

bool
ObjCLanguageRuntime::AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, const char *class_name)
{
    if (isa != 0)
    {
        m_isa_to_descriptor[isa] = descriptor_sp;
        // class_name is assumed to be valid
        m_hash_to_isa_map.insert(std::make_pair(MappedHash::HashStringUsingDJB(class_name), isa));
        return true;
    }
    return false;
}

void
ObjCLanguageRuntime::AddToMethodCache (lldb::addr_t class_addr, lldb::addr_t selector, lldb::addr_t impl_addr)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
    if (log)
    {
        log->Printf ("Caching: class 0x%" PRIx64 " selector 0x%" PRIx64 " implementation 0x%" PRIx64 ".", class_addr, selector, impl_addr);
    }
    m_impl_cache.insert (std::pair<ClassAndSel,lldb::addr_t> (ClassAndSel(class_addr, selector), impl_addr));
}

lldb::addr_t
ObjCLanguageRuntime::LookupInMethodCache (lldb::addr_t class_addr, lldb::addr_t selector)
{
    MsgImplMap::iterator pos, end = m_impl_cache.end();
    pos = m_impl_cache.find (ClassAndSel(class_addr, selector));
    if (pos != end)
        return (*pos).second;
    return LLDB_INVALID_ADDRESS;
}


lldb::TypeSP
ObjCLanguageRuntime::LookupInCompleteClassCache (ConstString &name)
{
    CompleteClassMap::iterator complete_class_iter = m_complete_class_cache.find(name);
    
    if (complete_class_iter != m_complete_class_cache.end())
    {
        // Check the weak pointer to make sure the type hasn't been unloaded
        TypeSP complete_type_sp (complete_class_iter->second.lock());
        
        if (complete_type_sp)
            return complete_type_sp;
        else
            m_complete_class_cache.erase(name);
    }
    
    if (m_negative_complete_class_cache.count(name) > 0)
        return TypeSP();
    
    const ModuleList &modules = m_process->GetTarget().GetImages();

    SymbolContextList sc_list;
    const size_t matching_symbols = modules.FindSymbolsWithNameAndType (name,
                                                                        eSymbolTypeObjCClass,
                                                                        sc_list);
    
    if (matching_symbols)
    {
        SymbolContext sc;
        
        sc_list.GetContextAtIndex(0, sc);
        
        ModuleSP module_sp(sc.module_sp);
        
        if (!module_sp)
            return TypeSP();
        
        const SymbolContext null_sc;
        const bool exact_match = true;
        const uint32_t max_matches = UINT32_MAX;
        TypeList types;
        
        const uint32_t num_types = module_sp->FindTypes (null_sc,
                                                         name,
                                                         exact_match,
                                                         max_matches,
                                                         types);
        
        if (num_types)
        {            
            uint32_t i;
            for (i = 0; i < num_types; ++i)
            {
                TypeSP type_sp (types.GetTypeAtIndex(i));
                
                if (type_sp->GetClangForwardType().IsObjCObjectOrInterfaceType())
                {
                    if (type_sp->IsCompleteObjCClass())
                    {
                        m_complete_class_cache[name] = type_sp;
                        return type_sp;
                    }
                }
            }
        }
    }
    m_negative_complete_class_cache.insert(name);
    return TypeSP();
}

size_t
ObjCLanguageRuntime::GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name)
{
    return LLDB_INVALID_IVAR_OFFSET;
}

void
ObjCLanguageRuntime::MethodName::Clear()
{
    m_full.Clear();
    m_class.Clear();
    m_category.Clear();
    m_selector.Clear();
    m_type = eTypeUnspecified;
    m_category_is_valid = false;
}

//bool
//ObjCLanguageRuntime::MethodName::SetName (const char *name, bool strict)
//{
//    Clear();
//    if (name && name[0])
//    {
//        // If "strict" is true. then the method must be specified with a
//        // '+' or '-' at the beginning. If "strict" is false, then the '+'
//        // or '-' can be omitted
//        bool valid_prefix = false;
//        
//        if (name[0] == '+' || name[0] == '-')
//        {
//            valid_prefix = name[1] == '[';
//        }
//        else if (!strict)
//        {
//            // "strict" is false, the name just needs to start with '['
//            valid_prefix = name[0] == '[';
//        }
//
//        if (valid_prefix)
//        {
//            static RegularExpression g_regex("^([-+]?)\\[([A-Za-z_][A-Za-z_0-9]*)(\\([A-Za-z_][A-Za-z_0-9]*\\))? ([A-Za-z_][A-Za-z_0-9:]*)\\]$");
//            llvm::StringRef matches[4];
//            // Since we are using a global regular expression, we must use the threadsafe version of execute
//            if (g_regex.ExecuteThreadSafe(name, matches, 4))
//            {
//                m_full.SetCString(name);
//                if (matches[0].empty())
//                    m_type = eTypeUnspecified;
//                else if (matches[0][0] == '+')
//                    m_type = eTypeClassMethod;
//                else
//                    m_type = eTypeInstanceMethod;
//                m_class.SetString(matches[1]);
//                m_selector.SetString(matches[3]);
//                if (!matches[2].empty())
//                    m_category.SetString(matches[2]);
//            }
//        }
//    }
//    return IsValid(strict);
//}

bool
ObjCLanguageRuntime::MethodName::SetName (const char *name, bool strict)
{
    Clear();
    if (name && name[0])
    {
        // If "strict" is true. then the method must be specified with a
        // '+' or '-' at the beginning. If "strict" is false, then the '+'
        // or '-' can be omitted
        bool valid_prefix = false;
        
        if (name[0] == '+' || name[0] == '-')
        {
            valid_prefix = name[1] == '[';
            if (name[0] == '+')
                m_type = eTypeClassMethod;
            else
                m_type = eTypeInstanceMethod;
        }
        else if (!strict)
        {
            // "strict" is false, the name just needs to start with '['
            valid_prefix = name[0] == '[';
        }
        
        if (valid_prefix)
        {
            int name_len = strlen (name);
            // Objective C methods must have at least:
            //      "-[" or "+[" prefix
            //      One character for a class name
            //      One character for the space between the class name
            //      One character for the method name
            //      "]" suffix
            if (name_len >= (5 + (strict ? 1 : 0)) && name[name_len - 1] == ']')
            {
                m_full.SetCStringWithLength(name, name_len);
            }
        }
    }
    return IsValid(strict);
}

const ConstString &
ObjCLanguageRuntime::MethodName::GetClassName ()
{
    if (!m_class)
    {
        if (IsValid(false))
        {
            const char *full = m_full.GetCString();
            const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
            const char *paren_pos = strchr (class_start, '(');
            if (paren_pos)
            {
                m_class.SetCStringWithLength (class_start, paren_pos - class_start);
            }
            else
            {
                // No '(' was found in the full name, we can definitively say
                // that our category was valid (and empty).
                m_category_is_valid = true;
                const char *space_pos = strchr (full, ' ');
                if (space_pos)
                {
                    m_class.SetCStringWithLength (class_start, space_pos - class_start);
                    if (!m_class_category)
                    {
                        // No category in name, so we can also fill in the m_class_category
                        m_class_category = m_class;
                    }
                }
            }
        }
    }
    return m_class;
}

const ConstString &
ObjCLanguageRuntime::MethodName::GetClassNameWithCategory () 
{
    if (!m_class_category)
    {
        if (IsValid(false))
        {
            const char *full = m_full.GetCString();
            const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
            const char *space_pos = strchr (full, ' ');
            if (space_pos)
            {
                m_class_category.SetCStringWithLength (class_start, space_pos - class_start);
                // If m_class hasn't been filled in and the class with category doesn't
                // contain a '(', then we can also fill in the m_class
                if (!m_class && strchr (m_class_category.GetCString(), '(') == NULL)
                {
                    m_class = m_class_category;
                    // No '(' was found in the full name, we can definitively say
                    // that our category was valid (and empty).
                    m_category_is_valid = true;

                }
            }
        }
    }
    return m_class_category;
}

const ConstString &
ObjCLanguageRuntime::MethodName::GetSelector ()
{
    if (!m_selector)
    {
        if (IsValid(false))
        {
            const char *full = m_full.GetCString();
            const char *space_pos = strchr (full, ' ');
            if (space_pos)
            {
                ++space_pos; // skip the space
                m_selector.SetCStringWithLength (space_pos, m_full.GetLength() - (space_pos - full) - 1);
            }
        }
    }
    return m_selector;
}

const ConstString &
ObjCLanguageRuntime::MethodName::GetCategory ()
{
    if (!m_category_is_valid && !m_category)
    {
        if (IsValid(false))
        {
            m_category_is_valid = true;
            const char *full = m_full.GetCString();
            const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
            const char *open_paren_pos = strchr (class_start, '(');
            if (open_paren_pos)
            {
                ++open_paren_pos; // Skip the open paren
                const char *close_paren_pos = strchr (open_paren_pos, ')');
                if (close_paren_pos)
                    m_category.SetCStringWithLength (open_paren_pos, close_paren_pos - open_paren_pos);
            }
        }
    }
    return m_category;
}

ConstString
ObjCLanguageRuntime::MethodName::GetFullNameWithoutCategory (bool empty_if_no_category)
{
    if (IsValid(false))
    {
        if (HasCategory())
        {
            StreamString strm;
            if (m_type == eTypeClassMethod)
                strm.PutChar('+');
            else if (m_type == eTypeInstanceMethod)
                strm.PutChar('-');
            strm.Printf("[%s %s]", GetClassName().GetCString(), GetSelector().GetCString());
            return ConstString(strm.GetString().c_str());
        }
        
        if (!empty_if_no_category)
        {
            // Just return the full name since it doesn't have a category
            return GetFullName();
        }
    }
    return ConstString();
}

size_t
ObjCLanguageRuntime::MethodName::GetFullNames (std::vector<ConstString> &names, bool append)
{
    if (!append)
        names.clear();
    if (IsValid(false))
    {
        StreamString strm;
        const bool is_class_method = m_type == eTypeClassMethod;
        const bool is_instance_method = m_type == eTypeInstanceMethod;
        const ConstString &category = GetCategory();
        if (is_class_method || is_instance_method)
        {
            names.push_back (m_full);
            if (category)
            {
                strm.Printf("%c[%s %s]",
                            is_class_method ? '+' : '-',
                            GetClassName().GetCString(),
                            GetSelector().GetCString());
                names.push_back(ConstString(strm.GetString().c_str()));
            }
        }
        else
        {
            const ConstString &class_name = GetClassName();
            const ConstString &selector = GetSelector();
            strm.Printf("+[%s %s]", class_name.GetCString(), selector.GetCString());
            names.push_back(ConstString(strm.GetString().c_str()));
            strm.Clear();
            strm.Printf("-[%s %s]", class_name.GetCString(), selector.GetCString());
            names.push_back(ConstString(strm.GetString().c_str()));
            strm.Clear();
            if (category)
            {
                strm.Printf("+[%s(%s) %s]", class_name.GetCString(), category.GetCString(), selector.GetCString());
                names.push_back(ConstString(strm.GetString().c_str()));
                strm.Clear();
                strm.Printf("-[%s(%s) %s]", class_name.GetCString(), category.GetCString(), selector.GetCString());
                names.push_back(ConstString(strm.GetString().c_str()));
            }
        }
    }
    return names.size();
}


bool
ObjCLanguageRuntime::ClassDescriptor::IsPointerValid (lldb::addr_t value,
                                                      uint32_t ptr_size,
                                                      bool allow_NULLs,
                                                      bool allow_tagged,
                                                      bool check_version_specific) const
{
    if (!value)
        return allow_NULLs;
    if ( (value % 2) == 1  && allow_tagged)
        return true;
    if ((value % ptr_size) == 0)
        return (check_version_specific ? CheckPointer(value,ptr_size) : true);
    else
        return false;
}

ObjCLanguageRuntime::ObjCISA
ObjCLanguageRuntime::GetISA(const ConstString &name)
{
    ISAToDescriptorIterator pos = GetDescriptorIterator (name);
    if (pos != m_isa_to_descriptor.end())
        return pos->first;
    return 0;
}

ObjCLanguageRuntime::ISAToDescriptorIterator
ObjCLanguageRuntime::GetDescriptorIterator (const ConstString &name)
{
    ISAToDescriptorIterator end = m_isa_to_descriptor.end();

    if (name)
    {
        UpdateISAToDescriptorMap();
        if (m_hash_to_isa_map.empty())
        {
            // No name hashes were provided, we need to just linearly power through the
            // names and find a match
            for (ISAToDescriptorIterator pos = m_isa_to_descriptor.begin(); pos != end; ++pos)
            {
                if (pos->second->GetClassName() == name)
                    return pos;
            }
        }
        else
        {
            // Name hashes were provided, so use them to efficiently lookup name to isa/descriptor
            const uint32_t name_hash = MappedHash::HashStringUsingDJB (name.GetCString());
            std::pair <HashToISAIterator, HashToISAIterator> range = m_hash_to_isa_map.equal_range(name_hash);
            for (HashToISAIterator range_pos = range.first; range_pos != range.second; ++range_pos)
            {
                ISAToDescriptorIterator pos = m_isa_to_descriptor.find (range_pos->second);
                if (pos != m_isa_to_descriptor.end())
                {
                    if (pos->second->GetClassName() == name)
                        return pos;
                }
            }
        }
    }
    return end;
}


ObjCLanguageRuntime::ObjCISA
ObjCLanguageRuntime::GetParentClass(ObjCLanguageRuntime::ObjCISA isa)
{
    ClassDescriptorSP objc_class_sp (GetClassDescriptorFromISA(isa));
    if (objc_class_sp)
    {
        ClassDescriptorSP objc_super_class_sp (objc_class_sp->GetSuperclass());
        if (objc_super_class_sp)
            return objc_super_class_sp->GetISA();
    }
    return 0;
}

ConstString
ObjCLanguageRuntime::GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa)
{
    ClassDescriptorSP objc_class_sp (GetNonKVOClassDescriptor(isa));
    if (objc_class_sp)
        return objc_class_sp->GetClassName();
    return ConstString();
}

ObjCLanguageRuntime::ClassDescriptorSP
ObjCLanguageRuntime::GetClassDescriptorFromClassName (const ConstString &class_name)
{
    ISAToDescriptorIterator pos = GetDescriptorIterator (class_name);
    if (pos != m_isa_to_descriptor.end())
        return pos->second;
    return ClassDescriptorSP();

}

ObjCLanguageRuntime::ClassDescriptorSP
ObjCLanguageRuntime::GetClassDescriptor (ValueObject& valobj)
{
    ClassDescriptorSP objc_class_sp;
    // if we get an invalid VO (which might still happen when playing around
    // with pointers returned by the expression parser, don't consider this
    // a valid ObjC object)
    if (valobj.GetClangType().IsValid())
    {
        addr_t isa_pointer = valobj.GetPointerValue();
        if (isa_pointer != LLDB_INVALID_ADDRESS)
        {
            ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
            
            Process *process = exe_ctx.GetProcessPtr();
            if (process)
            {
                Error error;
                ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error);
                if (isa != LLDB_INVALID_ADDRESS)
                    objc_class_sp = GetClassDescriptorFromISA (isa);
            }
        }
    }
    return objc_class_sp;
}

ObjCLanguageRuntime::ClassDescriptorSP
ObjCLanguageRuntime::GetNonKVOClassDescriptor (ValueObject& valobj)
{
    ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp (GetClassDescriptor (valobj));
    if (objc_class_sp)
    {
        if (!objc_class_sp->IsKVO())
            return objc_class_sp;
        
        ClassDescriptorSP non_kvo_objc_class_sp(objc_class_sp->GetSuperclass());
        if (non_kvo_objc_class_sp && non_kvo_objc_class_sp->IsValid())
            return non_kvo_objc_class_sp;
    }
    return ClassDescriptorSP();
}


ObjCLanguageRuntime::ClassDescriptorSP
ObjCLanguageRuntime::GetClassDescriptorFromISA (ObjCISA isa)
{
    if (isa)
    {
        UpdateISAToDescriptorMap();
        ObjCLanguageRuntime::ISAToDescriptorIterator pos = m_isa_to_descriptor.find(isa);    
        if (pos != m_isa_to_descriptor.end())
            return pos->second;
    }
    return ClassDescriptorSP();
}

ObjCLanguageRuntime::ClassDescriptorSP
ObjCLanguageRuntime::GetNonKVOClassDescriptor (ObjCISA isa)
{
    if (isa)
    {
        ClassDescriptorSP objc_class_sp = GetClassDescriptorFromISA (isa);
        if (objc_class_sp && objc_class_sp->IsValid())
        {
            if (!objc_class_sp->IsKVO())
                return objc_class_sp;

            ClassDescriptorSP non_kvo_objc_class_sp(objc_class_sp->GetSuperclass());
            if (non_kvo_objc_class_sp && non_kvo_objc_class_sp->IsValid())
                return non_kvo_objc_class_sp;
        }
    }
    return ClassDescriptorSP();
}



