//===-- LibCxxUnorderedMap.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/DataFormatters/CXXFormatterFunctions.h"

#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Host/Endian.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Target.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;

namespace lldb_private {
    namespace formatters {
        class LibcxxStdUnorderedMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd
        {
        public:
            LibcxxStdUnorderedMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
            
            virtual size_t
            CalculateNumChildren ();
            
            virtual lldb::ValueObjectSP
            GetChildAtIndex (size_t idx);
            
            virtual bool
            Update();
            
            virtual bool
            MightHaveChildren ();
            
            virtual size_t
            GetIndexOfChildWithName (const ConstString &name);
            
            virtual
            ~LibcxxStdUnorderedMapSyntheticFrontEnd ();
        private:
            
            ValueObject* m_tree;
            size_t m_num_elements;
            ValueObject* m_next_element;
            std::map<size_t,lldb::ValueObjectSP> m_children;
            std::vector<std::pair<ValueObject*, uint64_t> > m_elements_cache;
        };
    }
}

lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::LibcxxStdUnorderedMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
SyntheticChildrenFrontEnd(*valobj_sp.get()),
m_tree(NULL),
m_num_elements(0),
m_next_element(nullptr),
m_children(),
m_elements_cache()
{
    if (valobj_sp)
        Update();
}

size_t
lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::CalculateNumChildren ()
{
    if (m_num_elements != UINT32_MAX)
        return m_num_elements;
    return 0;
}

lldb::ValueObjectSP
lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::GetChildAtIndex (size_t idx)
{
    if (idx >= CalculateNumChildren())
        return lldb::ValueObjectSP();
    if (m_tree == NULL)
        return lldb::ValueObjectSP();
    
    auto cached = m_children.find(idx);
    if (cached != m_children.end())
        return cached->second;
    
    while (idx >= m_elements_cache.size())
    {
        if (m_next_element == nullptr)
            return lldb::ValueObjectSP();
        
        Error error;
        ValueObjectSP node_sp = m_next_element->Dereference(error);
        if (!node_sp || error.Fail())
            return lldb::ValueObjectSP();
        
        ValueObjectSP value_sp = node_sp->GetChildMemberWithName(ConstString("__value_"), true);
        ValueObjectSP hash_sp = node_sp->GetChildMemberWithName(ConstString("__hash_"), true);
        if (!hash_sp || !value_sp)
            return lldb::ValueObjectSP();
        m_elements_cache.push_back({value_sp.get(),hash_sp->GetValueAsUnsigned(0)});
        m_next_element = node_sp->GetChildMemberWithName(ConstString("__next_"),true).get();
        if (!m_next_element || m_next_element->GetValueAsUnsigned(0) == 0)
            m_next_element = nullptr;
    }
    
    std::pair<ValueObject*, uint64_t> val_hash = m_elements_cache[idx];
    if (!val_hash.first)
        return lldb::ValueObjectSP();
    StreamString stream;
    stream.Printf("[%" PRIu64 "]", (uint64_t)idx);
    DataExtractor data;
    Error error;
    val_hash.first->GetData(data, error);
    if (error.Fail())
        return lldb::ValueObjectSP();
    const bool thread_and_frame_only_if_stopped = true;
    ExecutionContext exe_ctx = val_hash.first->GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped);
    return val_hash.first->CreateValueObjectFromData(stream.GetData(),
                                                     data,
                                                     exe_ctx,
                                                     val_hash.first->GetClangType());
}

bool
lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::Update()
{
    m_num_elements = UINT32_MAX;
    m_next_element = nullptr;
    m_elements_cache.clear();
    m_children.clear();
    ValueObjectSP table_sp = m_backend.GetChildMemberWithName(ConstString("__table_"), true);
    if (!table_sp)
        return false;
    ValueObjectSP num_elements_sp = table_sp->GetChildAtNamePath({ConstString("__p2_"),ConstString("__first_")});
    if (!num_elements_sp)
        return false;
    m_num_elements = num_elements_sp->GetValueAsUnsigned(0);
    m_tree = table_sp->GetChildAtNamePath({ConstString("__p1_"),ConstString("__first_"),ConstString("__next_")}).get();
    if (m_num_elements > 0)
        m_next_element = table_sp->GetChildAtNamePath({ConstString("__p1_"),ConstString("__first_"),ConstString("__next_")}).get();
    return false;
}

bool
lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::MightHaveChildren ()
{
    return true;
}

size_t
lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
{
    return ExtractIndexFromString(name.GetCString());
}

lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::~LibcxxStdUnorderedMapSyntheticFrontEnd ()
{}

SyntheticChildrenFrontEnd*
lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
{
    if (!valobj_sp)
        return NULL;
    return (new LibcxxStdUnorderedMapSyntheticFrontEnd(valobj_sp));
}
