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

#include "lldb/Core/StreamString.h"
#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/DebugMacros.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"

using namespace lldb_private;

const char *
ExpressionSourceCode::g_expression_prefix = R"(
#ifndef NULL
#define NULL (__null)
#endif
#ifndef Nil
#define Nil (__null)
#endif
#ifndef nil
#define nil (__null)
#endif
#ifndef YES
#define YES ((BOOL)1)
#endif
#ifndef NO
#define NO ((BOOL)0)
#endif
typedef __INT8_TYPE__ int8_t;
typedef __UINT8_TYPE__ uint8_t;
typedef __INT16_TYPE__ int16_t;
typedef __UINT16_TYPE__ uint16_t;
typedef __INT32_TYPE__ int32_t;
typedef __UINT32_TYPE__ uint32_t;
typedef __INT64_TYPE__ int64_t;
typedef __UINT64_TYPE__ uint64_t;
typedef __INTPTR_TYPE__ intptr_t;
typedef __UINTPTR_TYPE__ uintptr_t;
typedef __SIZE_TYPE__ size_t;
typedef __PTRDIFF_TYPE__ ptrdiff_t;
typedef unsigned short unichar;
extern "C"
{
    int printf(const char * __restrict, ...);
}
)";

static const char *c_start_marker = "    /*LLDB_BODY_START*/\n    ";
static const char *c_end_marker   = ";\n    /*LLDB_BODY_END*/\n";

namespace {

class AddMacroState
{
    enum State
    {
        CURRENT_FILE_NOT_YET_PUSHED,
        CURRENT_FILE_PUSHED,
        CURRENT_FILE_POPPED
    };

public:
    AddMacroState(const FileSpec &current_file, const uint32_t current_file_line)
        : m_state(CURRENT_FILE_NOT_YET_PUSHED),
          m_current_file(current_file),
          m_current_file_line(current_file_line)
    { }

    void
    StartFile(const FileSpec &file)
    {
        m_file_stack.push_back(file);
        if (file == m_current_file)
            m_state = CURRENT_FILE_PUSHED;
    }

    void
    EndFile()
    {
        if (m_file_stack.size() == 0)
            return;

        FileSpec old_top = m_file_stack.back();
        m_file_stack.pop_back();
        if (old_top == m_current_file)
            m_state = CURRENT_FILE_POPPED;
    }

    // An entry is valid if it occurs before the current line in
    // the current file.
    bool
    IsValidEntry(uint32_t line)
    {
        switch (m_state)
        {
            case CURRENT_FILE_NOT_YET_PUSHED:
                return true;
            case CURRENT_FILE_PUSHED:
                // If we are in file included in the current file,
                // the entry should be added.
                if (m_file_stack.back() != m_current_file)
                    return true;

                if (line >= m_current_file_line)
                    return false;
                else
                    return true;
            default:
                return false;
        }
    }

private:
    std::vector<FileSpec> m_file_stack;
    State m_state;
    FileSpec m_current_file;
    uint32_t m_current_file_line;
};

} // anonymous namespace

static void
AddMacros(const DebugMacros *dm, CompileUnit *comp_unit, AddMacroState &state, StreamString &stream)
{
    if (dm == nullptr)
        return;

    for (size_t i = 0; i < dm->GetNumMacroEntries(); i++)
    {
        const DebugMacroEntry &entry = dm->GetMacroEntryAtIndex(i);
        uint32_t line;

        switch (entry.GetType())
        {
            case DebugMacroEntry::DEFINE:
                if (state.IsValidEntry(entry.GetLineNumber()))
                    stream.Printf("#define %s\n", entry.GetMacroString().AsCString());
                else
                    return;
                break;
            case DebugMacroEntry::UNDEF:
                if (state.IsValidEntry(entry.GetLineNumber()))
                    stream.Printf("#undef %s\n", entry.GetMacroString().AsCString());
                else
                    return;
                break;
            case DebugMacroEntry::START_FILE:
                line = entry.GetLineNumber();
                if (state.IsValidEntry(line))
                    state.StartFile(entry.GetFileSpec(comp_unit));
                else
                    return;
                break;
            case DebugMacroEntry::END_FILE:
                state.EndFile();
                break;
            case DebugMacroEntry::INDIRECT:
                AddMacros(entry.GetIndirectDebugMacros(), comp_unit, state, stream);
                break;
            default:
                // This is an unknown/invalid entry. Ignore.
                break;
        }
    }
}

static void
AddLocalVariableDecls(const lldb::VariableListSP &var_list_sp, StreamString &stream)
{
    for (size_t i = 0; i < var_list_sp->GetSize(); i++)
    {
        lldb::VariableSP var_sp = var_list_sp->GetVariableAtIndex(i);

        ConstString var_name = var_sp->GetName();
        if (!var_name || var_name == ConstString("this") || var_name == ConstString(".block_descriptor"))
            continue;

        stream.Printf("using $__lldb_local_vars::%s;\n", var_name.AsCString());
    }
}

bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrapping_language, bool static_method, ExecutionContext &exe_ctx) const
{
    const char *target_specific_defines = "typedef signed char BOOL;\n";
    std::string module_macros;
    
    Target *target = exe_ctx.GetTargetPtr();
    if (target)
    {
        if (target->GetArchitecture().GetMachine() == llvm::Triple::aarch64)
        {
            target_specific_defines = "typedef bool BOOL;\n";
        }
        if (target->GetArchitecture().GetMachine() == llvm::Triple::x86_64)
        {
            if (lldb::PlatformSP platform_sp = target->GetPlatform())
            {
                static ConstString g_platform_ios_simulator ("ios-simulator");
                if (platform_sp->GetPluginName() == g_platform_ios_simulator)
                {
                    target_specific_defines = "typedef bool BOOL;\n";
                }
            }
        }
        
        if (ClangModulesDeclVendor *decl_vendor = target->GetClangModulesDeclVendor())
        {
            ClangPersistentVariables *persistent_vars = llvm::cast<ClangPersistentVariables>(target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC));
            const ClangModulesDeclVendor::ModuleVector &hand_imported_modules = persistent_vars->GetHandLoadedClangModules();
            ClangModulesDeclVendor::ModuleVector modules_for_macros;
            
            for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules)
            {
                modules_for_macros.push_back(module);
            }
            
            if (target->GetEnableAutoImportClangModules())
            {
                if (StackFrame *frame = exe_ctx.GetFramePtr())
                {
                    if (Block *block = frame->GetFrameBlock())
                    {
                        SymbolContext sc;
                        
                        block->CalculateSymbolContext(&sc);
                        
                        if (sc.comp_unit)
                        {
                            StreamString error_stream;
                            
                            decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros, error_stream);
                        }
                    }
                }
            }
            
            decl_vendor->ForEachMacro(modules_for_macros, [&module_macros] (const std::string &expansion) -> bool {
                module_macros.append(expansion);
                module_macros.append("\n");
                return false;
            });
        }

    }

    StreamString debug_macros_stream;
    StreamString lldb_local_var_decls;
    if (StackFrame *frame = exe_ctx.GetFramePtr())
    {
        const SymbolContext &sc = frame->GetSymbolContext(
           lldb:: eSymbolContextCompUnit | lldb::eSymbolContextLineEntry);

        if (sc.comp_unit && sc.line_entry.IsValid())
        {
            DebugMacros *dm = sc.comp_unit->GetDebugMacros();
            if (dm)
            {
                AddMacroState state(sc.line_entry.file, sc.line_entry.line);
                AddMacros(dm, sc.comp_unit, state, debug_macros_stream);
            }
        }

        ConstString object_name;
        if (Language::LanguageIsCPlusPlus(frame->GetLanguage()))
        {
            if (target->GetInjectLocalVariables(&exe_ctx))
            {
                lldb::VariableListSP var_list_sp = frame->GetInScopeVariableList(false, true);
                AddLocalVariableDecls(var_list_sp, lldb_local_var_decls);
            }
        }
    }

    if (m_wrap)
    {
        switch (wrapping_language) 
        {
        default:
            return false;
        case lldb::eLanguageTypeC:
        case lldb::eLanguageTypeC_plus_plus:
        case lldb::eLanguageTypeObjC:
            break;
        }
        
        StreamString wrap_stream;
        
        wrap_stream.Printf("%s\n%s\n%s\n%s\n%s\n",
                           module_macros.c_str(),
                           debug_macros_stream.GetData(),
                           g_expression_prefix,
                           target_specific_defines,
                           m_prefix.c_str());
        
        // First construct a tagged form of the user expression so we can find it later:
        std::string tagged_body;
        switch (wrapping_language)
        {
            default:
                tagged_body = m_body;
                break;
            case lldb::eLanguageTypeC:
            case lldb::eLanguageTypeC_plus_plus:
            case lldb::eLanguageTypeObjC:
                tagged_body.append(c_start_marker);
                tagged_body.append(m_body);
                tagged_body.append(c_end_marker);
                break;
            
        }
        switch (wrapping_language) 
        {
        default:
            break;
        case lldb::eLanguageTypeC:
            wrap_stream.Printf("void                           \n"
                               "%s(void *$__lldb_arg)          \n"
                               "{                              \n"
                               "    %s;                        \n"
                               "%s"
                               "}                              \n",
                               m_name.c_str(),
                               lldb_local_var_decls.GetData(),
                               tagged_body.c_str());
            break;
        case lldb::eLanguageTypeC_plus_plus:
            wrap_stream.Printf("void                                   \n"
                               "$__lldb_class::%s(void *$__lldb_arg)   \n"
                               "{                                      \n"
                               "    %s;                                \n"
                               "%s"
                               "}                                      \n",
                               m_name.c_str(),
                               lldb_local_var_decls.GetData(),
                               tagged_body.c_str());
            break;
        case lldb::eLanguageTypeObjC:
            if (static_method)
            {
                wrap_stream.Printf("@interface $__lldb_objc_class ($__lldb_category)        \n"
                                   "+(void)%s:(void *)$__lldb_arg;                          \n"
                                   "@end                                                    \n"
                                   "@implementation $__lldb_objc_class ($__lldb_category)   \n"
                                   "+(void)%s:(void *)$__lldb_arg                           \n"
                                   "{                                                       \n"
                                   "%s"
                                   "}                                                       \n"
                                   "@end                                                    \n",
                                   m_name.c_str(),
                                   m_name.c_str(),
                                   tagged_body.c_str());
            }
            else
            {
                wrap_stream.Printf("@interface $__lldb_objc_class ($__lldb_category)       \n"
                                   "-(void)%s:(void *)$__lldb_arg;                         \n"
                                   "@end                                                   \n"
                                   "@implementation $__lldb_objc_class ($__lldb_category)  \n"
                                   "-(void)%s:(void *)$__lldb_arg                          \n"
                                   "{                                                      \n"
                                   "%s"
                                   "}                                                      \n"
                                   "@end                                                   \n",
                                   m_name.c_str(),
                                   m_name.c_str(),
                                   tagged_body.c_str());
            }
            break;
        }
        
        text = wrap_stream.GetString();
    }
    else
    {
        text.append(m_body);
    }

    return true;
}

bool
ExpressionSourceCode::GetOriginalBodyBounds(std::string transformed_text,
                                            lldb::LanguageType wrapping_language,
                                            size_t &start_loc,
                                            size_t &end_loc)
{
    const char *start_marker;
    const char *end_marker;
    
    switch (wrapping_language)
    {
    default:
        return false;
    case lldb::eLanguageTypeC:
    case lldb::eLanguageTypeC_plus_plus:
    case lldb::eLanguageTypeObjC:
        start_marker = c_start_marker;
        end_marker = c_end_marker;
        break;
    }
    
    start_loc = transformed_text.find(start_marker);
    if (start_loc == std::string::npos)
        return false;
    start_loc += strlen(start_marker);
    end_loc  = transformed_text.find(end_marker);
    if (end_loc == std::string::npos)
        return false;
    return true;
}

