//===-- ValueObjectPrinter.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/ValueObjectPrinter.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Debugger.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Target/Target.h"

using namespace lldb;
using namespace lldb_private;

DumpValueObjectOptions::DumpValueObjectOptions (ValueObject& valobj) :
DumpValueObjectOptions()
{
    m_use_dynamic = valobj.GetDynamicValueType();
    m_use_synthetic = valobj.IsSynthetic();
}

ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj,
                                        Stream* s)
{
    if (valobj)
    {
        DumpValueObjectOptions options(*valobj);
        Init (valobj,s,options,options.m_max_ptr_depth,0);
    }
    else
    {
        DumpValueObjectOptions options;
        Init (valobj,s,options,options.m_max_ptr_depth,0);
    }
}

ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj,
                                        Stream* s,
                                        const DumpValueObjectOptions& options)
{
    Init(valobj,s,options,options.m_max_ptr_depth,0);
}

ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj,
                                        Stream* s,
                                        const DumpValueObjectOptions& options,
                                        uint32_t ptr_depth,
                                        uint32_t curr_depth)
{
    Init(valobj,s,options,ptr_depth,curr_depth);
}

void
ValueObjectPrinter::Init (ValueObject* valobj,
                          Stream* s,
                          const DumpValueObjectOptions& options,
                          uint32_t ptr_depth,
                          uint32_t curr_depth)
{
    m_orig_valobj = valobj;
    m_valobj = nullptr;
    m_stream = s;
    this->options = options;
    m_ptr_depth = ptr_depth;
    m_curr_depth = curr_depth;
    assert (m_orig_valobj && "cannot print a NULL ValueObject");
    assert (m_stream && "cannot print to a NULL Stream");
    m_should_print = eLazyBoolCalculate;
    m_is_nil = eLazyBoolCalculate;
    m_is_ptr = eLazyBoolCalculate;
    m_is_ref = eLazyBoolCalculate;
    m_is_aggregate = eLazyBoolCalculate;
    m_summary_formatter = {nullptr,false};
    m_value.assign("");
    m_summary.assign("");
    m_error.assign("");
}

bool
ValueObjectPrinter::PrintValueObject ()
{
    if (!GetMostSpecializedValue () || m_valobj == nullptr)
        return false;
    
    if (ShouldPrintValueObject())
    {
        PrintValidationMarkerIfNeeded();
        
        PrintLocationIfNeeded();
        m_stream->Indent();
        
        bool show_type = PrintTypeIfNeeded();
        
        PrintNameIfNeeded(show_type);
    }

    bool value_printed = false;
    bool summary_printed = false;
    
    bool val_summary_ok = PrintValueAndSummaryIfNeeded (value_printed,summary_printed);

    if (val_summary_ok)
        PrintChildrenIfNeeded (value_printed, summary_printed);
    else
        m_stream->EOL();
    
    PrintValidationErrorIfNeeded();
    
    return true;
}

bool
ValueObjectPrinter::GetMostSpecializedValue ()
{
    if (m_valobj)
        return true;
    bool update_success = m_orig_valobj->UpdateValueIfNeeded (true);
    if (!update_success)
    {
        m_valobj = m_orig_valobj;
    }
    else
    {
        if (m_orig_valobj->IsDynamic())
        {
            if (options.m_use_dynamic == eNoDynamicValues)
            {
                ValueObject *static_value = m_orig_valobj->GetStaticValue().get();
                if (static_value)
                    m_valobj = static_value;
                else
                    m_valobj = m_orig_valobj;
            }
            else
                m_valobj = m_orig_valobj;
        }
        else
        {
            if (options.m_use_dynamic != eNoDynamicValues)
            {
                ValueObject *dynamic_value = m_orig_valobj->GetDynamicValue(options.m_use_dynamic).get();
                if (dynamic_value)
                    m_valobj = dynamic_value;
                else
                    m_valobj = m_orig_valobj;
            }
            else
                m_valobj = m_orig_valobj;
        }
        
        if (m_valobj->IsSynthetic())
        {
            if (options.m_use_synthetic == false)
            {
                ValueObject *non_synthetic = m_valobj->GetNonSyntheticValue().get();
                if (non_synthetic)
                    m_valobj = non_synthetic;
            }
        }
        else
        {
            if (options.m_use_synthetic == true)
            {
                ValueObject *synthetic = m_valobj->GetSyntheticValue().get();
                if (synthetic)
                    m_valobj = synthetic;
            }
        }
    }
    m_clang_type = m_valobj->GetClangType();
    m_type_flags = m_clang_type.GetTypeInfo ();
    return true;
}

const char*
ValueObjectPrinter::GetDescriptionForDisplay ()
{
    const char* str = m_valobj->GetObjectDescription();
    if (!str)
        str = m_valobj->GetSummaryAsCString();
    if (!str)
        str = m_valobj->GetValueAsCString();
    return str;
}

const char*
ValueObjectPrinter::GetRootNameForDisplay (const char* if_fail)
{
    const char *root_valobj_name = options.m_root_valobj_name.empty() ?
        m_valobj->GetName().AsCString() :
        options.m_root_valobj_name.c_str();
    return root_valobj_name ? root_valobj_name : if_fail;
}

bool
ValueObjectPrinter::ShouldPrintValueObject ()
{
    if (m_should_print == eLazyBoolCalculate)
        m_should_print = (options.m_flat_output == false || m_type_flags.Test (eTypeHasValue)) ? eLazyBoolYes : eLazyBoolNo;
    return m_should_print == eLazyBoolYes;
}

bool
ValueObjectPrinter::IsNil ()
{
    if (m_is_nil == eLazyBoolCalculate)
        m_is_nil = m_valobj->IsObjCNil() ? eLazyBoolYes : eLazyBoolNo;
    return m_is_nil == eLazyBoolYes;
}

bool
ValueObjectPrinter::IsPtr ()
{
    if (m_is_ptr == eLazyBoolCalculate)
        m_is_ptr = m_type_flags.Test (eTypeIsPointer) ? eLazyBoolYes : eLazyBoolNo;
    return m_is_ptr == eLazyBoolYes;
}

bool
ValueObjectPrinter::IsRef ()
{
    if (m_is_ref == eLazyBoolCalculate)
        m_is_ref = m_type_flags.Test (eTypeIsReference) ? eLazyBoolYes : eLazyBoolNo;
    return m_is_ref == eLazyBoolYes;
}

bool
ValueObjectPrinter::IsAggregate ()
{
    if (m_is_aggregate == eLazyBoolCalculate)
        m_is_aggregate = m_type_flags.Test (eTypeHasChildren) ? eLazyBoolYes : eLazyBoolNo;
    return m_is_aggregate == eLazyBoolYes;
}

bool
ValueObjectPrinter::PrintLocationIfNeeded ()
{
    if (options.m_show_location)
    {
        m_stream->Printf("%s: ", m_valobj->GetLocationAsCString());
        return true;
    }
    return false;
}

bool
ValueObjectPrinter::PrintTypeIfNeeded ()
{
    bool show_type = true;
    // if we are at the root-level and been asked to hide the root's type, then hide it
    if (m_curr_depth == 0 && options.m_hide_root_type)
        show_type = false;
    else
        // otherwise decide according to the usual rules (asked to show types - always at the root level)
        show_type = options.m_show_types || (m_curr_depth == 0 && !options.m_flat_output);
    
    if (show_type)
    {
        // Some ValueObjects don't have types (like registers sets). Only print
        // the type if there is one to print
        ConstString type_name;
        if (options.m_use_type_display_name)
            type_name = m_valobj->GetDisplayTypeName();
        else
            type_name = m_valobj->GetQualifiedTypeName();
        if (type_name)
            m_stream->Printf("(%s) ", type_name.GetCString());
        else
            show_type = false;
    }
    return show_type;
}

bool
ValueObjectPrinter::PrintNameIfNeeded (bool show_type)
{
    if (options.m_flat_output)
    {
        // If we are showing types, also qualify the C++ base classes
        const bool qualify_cxx_base_classes = show_type;
        if (!options.m_hide_name)
        {
            m_valobj->GetExpressionPath(*m_stream, qualify_cxx_base_classes);
            m_stream->PutCString(" =");
            return true;
        }
    }
    else if (!options.m_hide_name)
    {
        const char *name_cstr = GetRootNameForDisplay("");
        m_stream->Printf ("%s =", name_cstr);
        return true;
    }
    return false;
}

bool
ValueObjectPrinter::CheckScopeIfNeeded ()
{
    if (options.m_scope_already_checked)
        return true;
    return m_valobj->IsInScope();
}

TypeSummaryImpl*
ValueObjectPrinter::GetSummaryFormatter ()
{
    if (m_summary_formatter.second == false)
    {
        TypeSummaryImpl* entry = options.m_summary_sp ? options.m_summary_sp.get() : m_valobj->GetSummaryFormat().get();
        
        if (options.m_omit_summary_depth > 0)
            entry = NULL;
        m_summary_formatter.first = entry;
        m_summary_formatter.second = true;
    }
    return m_summary_formatter.first;
}

void
ValueObjectPrinter::GetValueSummaryError (std::string& value,
                                          std::string& summary,
                                          std::string& error)
{
    if (options.m_format != eFormatDefault && options.m_format != m_valobj->GetFormat())
    {
        m_valobj->GetValueAsCString(options.m_format,
                                    value);
    }
    else
    {
        const char* val_cstr = m_valobj->GetValueAsCString();
        if (val_cstr)
            value.assign(val_cstr);
    }
    const char* err_cstr = m_valobj->GetError().AsCString();
    if (err_cstr)
        error.assign(err_cstr);
    
    if (ShouldPrintValueObject())
    {
        if (IsNil())
            summary.assign("nil");
        else if (options.m_omit_summary_depth == 0)
        {
            TypeSummaryImpl* entry = GetSummaryFormatter();
            if (entry)
                m_valobj->GetSummaryAsCString(entry, summary);
            else
            {
                const char* sum_cstr = m_valobj->GetSummaryAsCString();
                if (sum_cstr)
                    summary.assign(sum_cstr);
            }
        }
    }
}

bool
ValueObjectPrinter::PrintValueAndSummaryIfNeeded (bool& value_printed,
                                                  bool& summary_printed)
{
    bool error_printed = false;
    if (ShouldPrintValueObject())
    {
        if (!CheckScopeIfNeeded())
            m_error.assign("out of scope");
        if (m_error.empty())
        {
            GetValueSummaryError(m_value, m_summary, m_error);
        }
        if (m_error.size())
        {
            error_printed = true;
            m_stream->Printf (" <%s>\n", m_error.c_str());
        }
        else
        {
            // Make sure we have a value and make sure the summary didn't
            // specify that the value should not be printed - and do not print
            // the value if this thing is nil
            // (but show the value if the user passes a format explicitly)
            TypeSummaryImpl* entry = GetSummaryFormatter();
            if (!IsNil() && !m_value.empty() && (entry == NULL || (entry->DoesPrintValue(m_valobj) || options.m_format != eFormatDefault) || m_summary.empty()) && !options.m_hide_value)
            {
                m_stream->Printf(" %s", m_value.c_str());
                value_printed = true;
            }
            
            if (m_summary.size())
            {
                m_stream->Printf(" %s", m_summary.c_str());
                summary_printed = true;
            }
        }
    }
    return !error_printed;
}

bool
ValueObjectPrinter::PrintObjectDescriptionIfNeeded (bool value_printed,
                                                    bool summary_printed)
{
    if (ShouldPrintValueObject())
    {
        // let's avoid the overly verbose no description error for a nil thing
        if (options.m_use_objc && !IsNil())
        {
            if (!options.m_hide_value || !options.m_hide_name)
                m_stream->Printf(" ");
            const char *object_desc = nullptr;
            if (value_printed || summary_printed)
                object_desc = m_valobj->GetObjectDescription();
            else
                object_desc = GetDescriptionForDisplay();
            if (object_desc && *object_desc)
            {
                m_stream->Printf("%s\n", object_desc);
                return true;
            }
            else if (value_printed == false && summary_printed == false)
                return true;
            else
                return false;
        }
    }
    return true;
}

bool
ValueObjectPrinter::ShouldPrintChildren (bool is_failed_description,
                                         uint32_t& curr_ptr_depth)
{
    const bool is_ref = IsRef ();
    const bool is_ptr = IsPtr ();

    if (is_failed_description || m_curr_depth < options.m_max_depth)
    {
        // We will show children for all concrete types. We won't show
        // pointer contents unless a pointer depth has been specified.
        // We won't reference contents unless the reference is the
        // root object (depth of zero).
        
        // Use a new temporary pointer depth in case we override the
        // current pointer depth below...
        
        if (is_ptr || is_ref)
        {
            // We have a pointer or reference whose value is an address.
            // Make sure that address is not NULL
            AddressType ptr_address_type;
            if (m_valobj->GetPointerValue (&ptr_address_type) == 0)
                return false;
            
            else if (is_ref && m_curr_depth == 0 && curr_ptr_depth == 0)
            {
                // If this is the root object (depth is zero) that we are showing
                // and it is a reference, and no pointer depth has been supplied
                // print out what it references. Don't do this at deeper depths
                // otherwise we can end up with infinite recursion...
                curr_ptr_depth = 1;
            }
            
            return (curr_ptr_depth > 0);
        }
        
        TypeSummaryImpl* entry = GetSummaryFormatter();

        return (!entry || entry->DoesPrintChildren(m_valobj) || m_summary.empty());
    }
    return false;
}

ValueObject*
ValueObjectPrinter::GetValueObjectForChildrenGeneration ()
{
    return m_valobj;
}

void
ValueObjectPrinter::PrintChildrenPreamble ()
{
    if (options.m_flat_output)
    {
        if (ShouldPrintValueObject())
            m_stream->EOL();
    }
    else
    {
        if (ShouldPrintValueObject())
            m_stream->PutCString(IsRef () ? ": {\n" : " {\n");
        m_stream->IndentMore();
    }
}

void
ValueObjectPrinter::PrintChild (ValueObjectSP child_sp,
                                uint32_t curr_ptr_depth)
{
    DumpValueObjectOptions child_options(options);
    child_options.SetFormat(options.m_format).SetSummary().SetRootValueObjectName();
    child_options.SetScopeChecked(true).SetHideName(options.m_hide_name).SetHideValue(options.m_hide_value)
    .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - 1 : 0);
    if (child_sp.get())
    {
        ValueObjectPrinter child_printer(child_sp.get(),
                                         m_stream,
                                         child_options,
                                         (IsPtr() || IsRef()) && curr_ptr_depth >= 1 ? curr_ptr_depth - 1 : curr_ptr_depth,
                                         m_curr_depth + 1);
        child_printer.PrintValueObject();
    }

}

uint32_t
ValueObjectPrinter::GetMaxNumChildrenToPrint (bool& print_dotdotdot)
{
    ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
    
    size_t num_children = synth_m_valobj->GetNumChildren();
    print_dotdotdot = false;
    if (num_children)
    {
        const size_t max_num_children = m_valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
        
        if (num_children > max_num_children && !options.m_ignore_cap)
        {
            print_dotdotdot = true;
            return max_num_children;
        }
    }
    return num_children;
}

void
ValueObjectPrinter::PrintChildrenPostamble (bool print_dotdotdot)
{
    if (!options.m_flat_output)
    {
        if (print_dotdotdot)
        {
            m_valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().ChildrenTruncated();
            m_stream->Indent("...\n");
        }
        m_stream->IndentLess();
        m_stream->Indent("}\n");
    }
}

void
ValueObjectPrinter::PrintChildren (uint32_t curr_ptr_depth)
{
    ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
    
    bool print_dotdotdot = false;
    size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot);
    if (num_children)
    {
        PrintChildrenPreamble ();
        
        for (size_t idx=0; idx<num_children; ++idx)
        {
            ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true));
            PrintChild (child_sp, curr_ptr_depth);
        }
        
        PrintChildrenPostamble (print_dotdotdot);
    }
    else if (IsAggregate())
    {
        // Aggregate, no children...
        if (ShouldPrintValueObject())
        {
            // if it has a synthetic value, then don't print {}, the synthetic children are probably only being used to vend a value
            if (m_valobj->DoesProvideSyntheticValue())
                m_stream->PutCString( "\n");
            else
                m_stream->PutCString(" {}\n");
        }
    }
    else
    {
        if (ShouldPrintValueObject())
            m_stream->EOL();
    }
}

bool
ValueObjectPrinter::PrintChildrenOneLiner (bool hide_names)
{
    if (!GetMostSpecializedValue () || m_valobj == nullptr)
        return false;
    
    ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
    
    bool print_dotdotdot = false;
    size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot);
    
    if (num_children)
    {
        m_stream->PutChar('(');
        
        for (uint32_t idx=0; idx<num_children; ++idx)
        {
            lldb::ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true));
            if (child_sp)
                child_sp = child_sp->GetQualifiedRepresentationIfAvailable(options.m_use_dynamic, options.m_use_synthetic);
            if (child_sp)
            {
                if (idx)
                    m_stream->PutCString(", ");
                if (!hide_names)
                {
                    const char* name = child_sp.get()->GetName().AsCString();
                    if (name && *name)
                    {
                        m_stream->PutCString(name);
                        m_stream->PutCString(" = ");
                    }
                }
                child_sp->DumpPrintableRepresentation(*m_stream,
                                                      ValueObject::eValueObjectRepresentationStyleSummary,
                                                      lldb::eFormatInvalid,
                                                      ValueObject::ePrintableRepresentationSpecialCasesDisable);
            }
        }
        
        if (print_dotdotdot)
            m_stream->PutCString(", ...)");
        else
            m_stream->PutChar(')');
    }
    return true;
}

void
ValueObjectPrinter::PrintChildrenIfNeeded (bool value_printed,
                                           bool summary_printed)
{
    // this flag controls whether we tried to display a description for this object and failed
    // if that happens, we want to display the children, if any
    bool is_failed_description = !PrintObjectDescriptionIfNeeded(value_printed, summary_printed);
    
    uint32_t curr_ptr_depth = m_ptr_depth;
    bool print_children = ShouldPrintChildren (is_failed_description,curr_ptr_depth);
    bool print_oneline = (curr_ptr_depth > 0 ||
                          options.m_show_types ||
                          !options.m_allow_oneliner_mode ||
                          options.m_flat_output ||
                          options.m_show_location) ? false : DataVisualization::ShouldPrintAsOneLiner(*m_valobj);
    
    if (print_children)
    {
        if (print_oneline)
        {
            m_stream->PutChar(' ');
            PrintChildrenOneLiner (false);
            m_stream->EOL();
        }
        else
            PrintChildren (curr_ptr_depth);
    }
    else if (m_curr_depth >= options.m_max_depth && IsAggregate() && ShouldPrintValueObject())
    {
            m_stream->PutCString("{...}\n");
    }
    else
        m_stream->EOL();
}

bool
ValueObjectPrinter::ShouldPrintValidation ()
{
    return options.m_run_validator;
}

bool
ValueObjectPrinter::PrintValidationMarkerIfNeeded ()
{
    if (!ShouldPrintValidation())
        return false;
    
    m_validation = m_valobj->GetValidationStatus();
    
    if (TypeValidatorResult::Failure == m_validation.first)
    {
        m_stream->Printf("! ");
        return true;
    }
    
    return false;
}

bool
ValueObjectPrinter::PrintValidationErrorIfNeeded ()
{
    if (!ShouldPrintValidation())
        return false;
    
    if (TypeValidatorResult::Success == m_validation.first)
        return false;
    
    if (m_validation.second.empty())
        m_validation.second.assign("unknown error");
    
    m_stream->Printf(" ! validation error: %s", m_validation.second.c_str());
    m_stream->EOL();
    
    return true;
}
