//===-- GoUserExpression.cpp ------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// C Includes
#include <stdio.h>
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

// C++ Includes
#include <cstdlib>
#include <memory>
#include <string>
#include <vector>

// Other libraries and framework includes
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringMap.h"

// Project includes
#include "GoUserExpression.h"

#include "lldb/Core/ConstString.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataEncoder.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectRegister.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Symbol/GoASTContext.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Target/ThreadPlanCallUserExpression.h"
#include "lldb/lldb-private.h"

#include "Plugins/ExpressionParser/Go/GoAST.h"
#include "Plugins/ExpressionParser/Go/GoParser.h"

using namespace lldb_private;
using namespace lldb;

class GoUserExpression::GoInterpreter
{
  public:
    GoInterpreter(ExecutionContext &exe_ctx, const char *expr)
        : m_exe_ctx(exe_ctx), m_frame(exe_ctx.GetFrameSP()), m_parser(expr)
    {
        if (m_frame)
        {
            const SymbolContext &ctx = m_frame->GetSymbolContext(eSymbolContextFunction);
            ConstString fname = ctx.GetFunctionName();
            if (fname.GetLength() > 0)
            {
                size_t dot = fname.GetStringRef().find('.');
                if (dot != llvm::StringRef::npos)
                    m_package = llvm::StringRef(fname.AsCString(), dot);
            }
        }
    }

    void
    set_use_dynamic(DynamicValueType use_dynamic)
    {
        m_use_dynamic = use_dynamic;
    }

    bool Parse();
    lldb::ValueObjectSP Evaluate(ExecutionContext &exe_ctx);
    lldb::ValueObjectSP EvaluateStatement(const GoASTStmt *s);
    lldb::ValueObjectSP EvaluateExpr(const GoASTExpr *e);

    ValueObjectSP
    VisitBadExpr(const GoASTBadExpr *e)
    {
        m_parser.GetError(m_error);
        return nullptr;
    }

    ValueObjectSP VisitParenExpr(const GoASTParenExpr *e);
    ValueObjectSP VisitIdent(const GoASTIdent *e);
    ValueObjectSP VisitStarExpr(const GoASTStarExpr *e);
    ValueObjectSP VisitSelectorExpr(const GoASTSelectorExpr *e);
    ValueObjectSP VisitBasicLit(const GoASTBasicLit *e);
    ValueObjectSP VisitIndexExpr(const GoASTIndexExpr *e);
    ValueObjectSP VisitUnaryExpr(const GoASTUnaryExpr *e);
    ValueObjectSP VisitCallExpr(const GoASTCallExpr *e);

    ValueObjectSP
    VisitTypeAssertExpr(const GoASTTypeAssertExpr *e)
    {
        return NotImplemented(e);
    }

    ValueObjectSP
    VisitBinaryExpr(const GoASTBinaryExpr *e)
    {
        return NotImplemented(e);
    }

    ValueObjectSP
    VisitArrayType(const GoASTArrayType *e)
    {
        return NotImplemented(e);
    }

    ValueObjectSP
    VisitChanType(const GoASTChanType *e)
    {
        return NotImplemented(e);
    }

    ValueObjectSP
    VisitCompositeLit(const GoASTCompositeLit *e)
    {
        return NotImplemented(e);
    }

    ValueObjectSP
    VisitEllipsis(const GoASTEllipsis *e)
    {
        return NotImplemented(e);
    }

    ValueObjectSP
    VisitFuncType(const GoASTFuncType *e)
    {
        return NotImplemented(e);
    }

    ValueObjectSP
    VisitFuncLit(const GoASTFuncLit *e)
    {
        return NotImplemented(e);
    }

    ValueObjectSP
    VisitInterfaceType(const GoASTInterfaceType *e)
    {
        return NotImplemented(e);
    }

    ValueObjectSP
    VisitKeyValueExpr(const GoASTKeyValueExpr *e)
    {
        return NotImplemented(e);
    }

    ValueObjectSP
    VisitMapType(const GoASTMapType *e)
    {
        return NotImplemented(e);
    }

    ValueObjectSP
    VisitSliceExpr(const GoASTSliceExpr *e)
    {
        return NotImplemented(e);
    }

    ValueObjectSP
    VisitStructType(const GoASTStructType *e)
    {
        return NotImplemented(e);
    }

    CompilerType EvaluateType(const GoASTExpr *e);

    Error &
    error()
    {
        return m_error;
    }

  private:
    std::nullptr_t
    NotImplemented(const GoASTExpr *e)
    {
        m_error.SetErrorStringWithFormat("%s node not implemented", e->GetKindName());
        return nullptr;
    }

    ExecutionContext m_exe_ctx;
    lldb::StackFrameSP m_frame;
    GoParser m_parser;
    DynamicValueType m_use_dynamic;
    Error m_error;
    llvm::StringRef m_package;
    std::vector<std::unique_ptr<GoASTStmt>> m_statements;
};

VariableSP
FindGlobalVariable(TargetSP target, llvm::Twine name)
{
    ConstString fullname(name.str());
    VariableList variable_list;
    const bool append = true;
    if (!target)
    {
        return nullptr;
    }
    const uint32_t match_count = target->GetImages().FindGlobalVariables(fullname, append, 1, variable_list);
    if (match_count == 1)
    {
        return variable_list.GetVariableAtIndex(0);
    }
    return nullptr;
}

CompilerType
LookupType(TargetSP target, ConstString name)
{
    if (!target)
        return CompilerType();
    SymbolContext sc;
    TypeList type_list;
    llvm::DenseSet<SymbolFile *> searched_symbol_files;
    uint32_t num_matches = target->GetImages().FindTypes(sc, name, false, 2, searched_symbol_files, type_list);
    if (num_matches > 0)
    {
        return type_list.GetTypeAtIndex(0)->GetFullCompilerType();
    }
    return CompilerType();
}

GoUserExpression::GoUserExpression(ExecutionContextScope &exe_scope, const char *expr, const char *expr_prefix,
                                   lldb::LanguageType language, ResultType desired_type,
                                   const EvaluateExpressionOptions &options)
    : UserExpression(exe_scope, expr, expr_prefix, language, desired_type, options)
{
}

bool
GoUserExpression::Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
                        lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory,
                        bool generate_debug_info)
{
    InstallContext(exe_ctx);
    m_interpreter.reset(new GoInterpreter(exe_ctx, GetUserText()));
    if (m_interpreter->Parse())
        return true;
    const char *error_cstr = m_interpreter->error().AsCString();
    if (error_cstr && error_cstr[0])
        diagnostic_manager.PutCString(eDiagnosticSeverityError, error_cstr);
    else
        diagnostic_manager.Printf(eDiagnosticSeverityError, "expression can't be interpreted or run");
    return false;
}

lldb::ExpressionResults
GoUserExpression::DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
                            const EvaluateExpressionOptions &options, lldb::UserExpressionSP &shared_ptr_to_me,
                            lldb::ExpressionVariableSP &result)
{
    Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));

    lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
    lldb::ExpressionResults execution_results = lldb::eExpressionSetupError;

    Process *process = exe_ctx.GetProcessPtr();
    Target *target = exe_ctx.GetTargetPtr();

    if (target == nullptr || process == nullptr || process->GetState() != lldb::eStateStopped)
    {
        if (execution_policy == eExecutionPolicyAlways)
        {
            if (log)
                log->Printf("== [GoUserExpression::Evaluate] Expression may not run, but is not constant ==");

            diagnostic_manager.PutCString(eDiagnosticSeverityError, "expression needed to run but couldn't");

            return execution_results;
        }
    }

    m_interpreter->set_use_dynamic(options.GetUseDynamic());
    ValueObjectSP result_val_sp = m_interpreter->Evaluate(exe_ctx);
    Error err = m_interpreter->error();
    m_interpreter.reset();

    if (!result_val_sp)
    {
        const char *error_cstr = err.AsCString();
        if (error_cstr && error_cstr[0])
            diagnostic_manager.PutCString(eDiagnosticSeverityError, error_cstr);
        else
            diagnostic_manager.PutCString(eDiagnosticSeverityError, "expression can't be interpreted or run");
        return lldb::eExpressionDiscarded;
    }
    result.reset(new ExpressionVariable(ExpressionVariable::eKindGo));
    result->m_live_sp = result->m_frozen_sp = result_val_sp;
    result->m_flags |= ExpressionVariable::EVIsProgramReference;
    PersistentExpressionState *pv = target->GetPersistentExpressionStateForLanguage(eLanguageTypeGo);
    if (pv != nullptr)
    {
        result->SetName(pv->GetNextPersistentVariableName());
        pv->AddVariable(result);
    }
    return lldb::eExpressionCompleted;
}

bool
GoUserExpression::GoInterpreter::Parse()
{
    for (std::unique_ptr<GoASTStmt> stmt(m_parser.Statement()); stmt; stmt.reset(m_parser.Statement()))
    {
        if (m_parser.Failed())
            break;
        m_statements.emplace_back(std::move(stmt));
    }
    if (m_parser.Failed() || !m_parser.AtEOF())
        m_parser.GetError(m_error);

    return m_error.Success();
}

ValueObjectSP
GoUserExpression::GoInterpreter::Evaluate(ExecutionContext &exe_ctx)
{
    m_exe_ctx = exe_ctx;
    ValueObjectSP result;
    for (const std::unique_ptr<GoASTStmt> &stmt : m_statements)
    {
        result = EvaluateStatement(stmt.get());
        if (m_error.Fail())
            return nullptr;
    }
    return result;
}

ValueObjectSP
GoUserExpression::GoInterpreter::EvaluateStatement(const lldb_private::GoASTStmt *stmt)
{
    ValueObjectSP result;
    switch (stmt->GetKind())
    {
        case GoASTNode::eBlockStmt:
        {
            const GoASTBlockStmt *block = llvm::cast<GoASTBlockStmt>(stmt);
            for (size_t i = 0; i < block->NumList(); ++i)
                result = EvaluateStatement(block->GetList(i));
            break;
        }
        case GoASTNode::eBadStmt:
            m_parser.GetError(m_error);
            break;
        case GoASTNode::eExprStmt:
        {
            const GoASTExprStmt *expr = llvm::cast<GoASTExprStmt>(stmt);
            return EvaluateExpr(expr->GetX());
        }
        default:
            m_error.SetErrorStringWithFormat("%s node not supported", stmt->GetKindName());
    }
    return result;
}

ValueObjectSP
GoUserExpression::GoInterpreter::EvaluateExpr(const lldb_private::GoASTExpr *e)
{
    if (e)
        return e->Visit<ValueObjectSP>(this);
    return ValueObjectSP();
}

ValueObjectSP
GoUserExpression::GoInterpreter::VisitParenExpr(const lldb_private::GoASTParenExpr *e)
{
    return EvaluateExpr(e->GetX());
}

ValueObjectSP
GoUserExpression::GoInterpreter::VisitIdent(const GoASTIdent *e)
{
    ValueObjectSP val;
    if (m_frame)
    {
        VariableSP var_sp;
        std::string varname = e->GetName().m_value.str();
        if (varname.size() > 1 && varname[0] == '$')
        {
            RegisterContextSP reg_ctx_sp = m_frame->GetRegisterContext();
            const RegisterInfo *reg = reg_ctx_sp->GetRegisterInfoByName(varname.c_str() + 1);
            if (reg)
            {
                std::string type;
                switch (reg->encoding)
                {
                    case lldb::eEncodingSint:
                        type.append("int");
                        break;
                    case lldb::eEncodingUint:
                        type.append("uint");
                        break;
                    case lldb::eEncodingIEEE754:
                        type.append("float");
                        break;
                    default:
                        m_error.SetErrorString("Invaild register encoding");
                        return nullptr;
                }
                switch (reg->byte_size)
                {
                    case 8:
                        type.append("64");
                        break;
                    case 4:
                        type.append("32");
                        break;
                    case 2:
                        type.append("16");
                        break;
                    case 1:
                        type.append("8");
                        break;
                    default:
                        m_error.SetErrorString("Invaild register size");
                        return nullptr;
                }
                ValueObjectSP regVal =
                    ValueObjectRegister::Create(m_frame.get(), reg_ctx_sp, reg->kinds[eRegisterKindLLDB]);
                CompilerType goType = LookupType(m_frame->CalculateTarget(), ConstString(type));
                if (regVal)
                {
                    regVal = regVal->Cast(goType);
                    return regVal;
                }
            }
            m_error.SetErrorString("Invaild register name");
            return nullptr;
        }
        VariableListSP var_list_sp(m_frame->GetInScopeVariableList(false));
        if (var_list_sp)
        {
            var_sp = var_list_sp->FindVariable(ConstString(varname));
            if (var_sp)
                val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic);
            else
            {
                // When a variable is on the heap instead of the stack, go records a variable
                // '&x' instead of 'x'.
                var_sp = var_list_sp->FindVariable(ConstString("&" + varname));
                if (var_sp)
                {
                    val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic);
                    if (val)
                        val = val->Dereference(m_error);
                    if (m_error.Fail())
                        return nullptr;
                }
            }
        }
        if (!val)
        {
            m_error.Clear();
            TargetSP target = m_frame->CalculateTarget();
            if (!target)
            {
                m_error.SetErrorString("No target");
                return nullptr;
            }
            var_sp = FindGlobalVariable(target, m_package + "." + e->GetName().m_value);
            if (var_sp)
                return m_frame->TrackGlobalVariable(var_sp, m_use_dynamic);
        }
    }
    if (!val)
        m_error.SetErrorStringWithFormat("Unknown variable %s", e->GetName().m_value.str().c_str());
    return val;
}

ValueObjectSP
GoUserExpression::GoInterpreter::VisitStarExpr(const GoASTStarExpr *e)
{
    ValueObjectSP target = EvaluateExpr(e->GetX());
    if (!target)
        return nullptr;
    return target->Dereference(m_error);
}

ValueObjectSP
GoUserExpression::GoInterpreter::VisitSelectorExpr(const lldb_private::GoASTSelectorExpr *e)
{
    ValueObjectSP target = EvaluateExpr(e->GetX());
    if (target)
    {
        if (target->GetCompilerType().IsPointerType())
        {
            target = target->Dereference(m_error);
            if (m_error.Fail())
                return nullptr;
        }
        ConstString field(e->GetSel()->GetName().m_value);
        ValueObjectSP result = target->GetChildMemberWithName(field, true);
        if (!result)
            m_error.SetErrorStringWithFormat("Unknown child %s", field.AsCString());
        return result;
    }
    if (const GoASTIdent *package = llvm::dyn_cast<GoASTIdent>(e->GetX()))
    {
        if (VariableSP global = FindGlobalVariable(m_exe_ctx.GetTargetSP(),
                                                   package->GetName().m_value + "." + e->GetSel()->GetName().m_value))
        {
            if (m_frame)
            {
                m_error.Clear();
                return m_frame->GetValueObjectForFrameVariable(global, m_use_dynamic);
            }
        }
    }
    if (const GoASTBasicLit *packageLit = llvm::dyn_cast<GoASTBasicLit>(e->GetX()))
    {
        if (packageLit->GetValue().m_type == GoLexer::LIT_STRING)
        {
            std::string value = packageLit->GetValue().m_value.str();
            value = value.substr(1, value.size() - 2);
            if (VariableSP global =
                    FindGlobalVariable(m_exe_ctx.GetTargetSP(), value + "." + e->GetSel()->GetName().m_value))
            {
                if (m_frame)
                {
                    m_error.Clear();
                    return m_frame->TrackGlobalVariable(global, m_use_dynamic);
                }
            }
        }
    }
    // EvaluateExpr should have already set m_error.
    return target;
}

ValueObjectSP
GoUserExpression::GoInterpreter::VisitBasicLit(const lldb_private::GoASTBasicLit *e)
{
    std::string value = e->GetValue().m_value.str();
    if (e->GetValue().m_type != GoLexer::LIT_INTEGER)
    {
        m_error.SetErrorStringWithFormat("Unsupported literal %s", value.c_str());
        return nullptr;
    }
    errno = 0;
    int64_t intvalue = strtol(value.c_str(), nullptr, 0);
    if (errno != 0)
    {
        m_error.SetErrorToErrno();
        return nullptr;
    }
    DataBufferSP buf(new DataBufferHeap(sizeof(intvalue), 0));
    TargetSP target = m_exe_ctx.GetTargetSP();
    if (!target)
    {
        m_error.SetErrorString("No target");
        return nullptr;
    }
    ByteOrder order = target->GetArchitecture().GetByteOrder();
    uint8_t addr_size = target->GetArchitecture().GetAddressByteSize();
    DataEncoder enc(buf, order, addr_size);
    enc.PutU64(0, static_cast<uint64_t>(intvalue));
    DataExtractor data(buf, order, addr_size);

    CompilerType type = LookupType(target, ConstString("int64"));
    return ValueObject::CreateValueObjectFromData(nullptr, data, m_exe_ctx, type);
}

ValueObjectSP
GoUserExpression::GoInterpreter::VisitIndexExpr(const lldb_private::GoASTIndexExpr *e)
{
    ValueObjectSP target = EvaluateExpr(e->GetX());
    if (!target)
        return nullptr;
    ValueObjectSP index = EvaluateExpr(e->GetIndex());
    if (!index)
        return nullptr;
    bool is_signed;
    if (!index->GetCompilerType().IsIntegerType(is_signed))
    {
        m_error.SetErrorString("Unsupported index");
        return nullptr;
    }
    size_t idx;
    if (is_signed)
        idx = index->GetValueAsSigned(0);
    else
        idx = index->GetValueAsUnsigned(0);
    if (GoASTContext::IsGoSlice(target->GetCompilerType()))
    {
        target = target->GetStaticValue();
        ValueObjectSP cap = target->GetChildMemberWithName(ConstString("cap"), true);
        if (cap)
        {
            uint64_t capval = cap->GetValueAsUnsigned(0);
            if (idx >= capval)
            {
                m_error.SetErrorStringWithFormat("Invalid index %" PRIu64 " , cap = %" PRIu64, uint64_t(idx), capval);
                return nullptr;
            }
        }
        target = target->GetChildMemberWithName(ConstString("array"), true);
        if (target && m_use_dynamic != eNoDynamicValues)
        {
            ValueObjectSP dynamic = target->GetDynamicValue(m_use_dynamic);
            if (dynamic)
                target = dynamic;
        }
        if (!target)
            return nullptr;
        return target->GetSyntheticArrayMember(idx, true);
    }
    return target->GetChildAtIndex(idx, true);
}

ValueObjectSP
GoUserExpression::GoInterpreter::VisitUnaryExpr(const GoASTUnaryExpr *e)
{
    ValueObjectSP x = EvaluateExpr(e->GetX());
    if (!x)
        return nullptr;
    switch (e->GetOp())
    {
        case GoLexer::OP_AMP:
        {
            CompilerType type = x->GetCompilerType().GetPointerType();
            uint64_t address = x->GetAddressOf();
            return ValueObject::CreateValueObjectFromAddress(nullptr, address, m_exe_ctx, type);
        }
        case GoLexer::OP_PLUS:
            return x;
        default:
            m_error.SetErrorStringWithFormat("Operator %s not supported",
                                             GoLexer::LookupToken(e->GetOp()).str().c_str());
            return nullptr;
    }
}

CompilerType
GoUserExpression::GoInterpreter::EvaluateType(const GoASTExpr *e)
{
    TargetSP target = m_exe_ctx.GetTargetSP();
    if (auto *id = llvm::dyn_cast<GoASTIdent>(e))
    {
        CompilerType result = LookupType(target, ConstString(id->GetName().m_value));
        if (result.IsValid())
            return result;
        std::string fullname = (m_package + "." + id->GetName().m_value).str();
        result = LookupType(target, ConstString(fullname));
        if (!result)
            m_error.SetErrorStringWithFormat("Unknown type %s", fullname.c_str());
        return result;
    }
    if (auto *sel = llvm::dyn_cast<GoASTSelectorExpr>(e))
    {
        std::string package;
        if (auto *pkg_node = llvm::dyn_cast<GoASTIdent>(sel->GetX()))
        {
            package = pkg_node->GetName().m_value.str();
        }
        else if (auto *str_node = llvm::dyn_cast<GoASTBasicLit>(sel->GetX()))
        {
            if (str_node->GetValue().m_type == GoLexer::LIT_STRING)
            {
                package = str_node->GetValue().m_value.substr(1).str();
                package.resize(package.length() - 1);
            }
        }
        if (package.empty())
        {
            m_error.SetErrorStringWithFormat("Invalid %s in type expression", sel->GetX()->GetKindName());
            return CompilerType();
        }
        std::string fullname = (package + "." + sel->GetSel()->GetName().m_value).str();
        CompilerType result = LookupType(target, ConstString(fullname));
        if (!result)
            m_error.SetErrorStringWithFormat("Unknown type %s", fullname.c_str());
        return result;
    }
    if (auto *star = llvm::dyn_cast<GoASTStarExpr>(e))
    {
        CompilerType elem = EvaluateType(star->GetX());
        return elem.GetPointerType();
    }
    if (auto *paren = llvm::dyn_cast<GoASTParenExpr>(e))
        return EvaluateType(paren->GetX());
    if (auto *array = llvm::dyn_cast<GoASTArrayType>(e))
    {
        CompilerType elem = EvaluateType(array->GetElt());
    }

    m_error.SetErrorStringWithFormat("Invalid %s in type expression", e->GetKindName());
    return CompilerType();
}

ValueObjectSP
GoUserExpression::GoInterpreter::VisitCallExpr(const lldb_private::GoASTCallExpr *e)
{
    ValueObjectSP x = EvaluateExpr(e->GetFun());
    if (x || e->NumArgs() != 1)
    {
        m_error.SetErrorStringWithFormat("Code execution not supported");
        return nullptr;
    }
    m_error.Clear();
    CompilerType type = EvaluateType(e->GetFun());
    if (!type)
    {
        return nullptr;
    }
    ValueObjectSP value = EvaluateExpr(e->GetArgs(0));
    if (!value)
        return nullptr;
    // TODO: Handle special conversions
    return value->Cast(type);
}

GoPersistentExpressionState::GoPersistentExpressionState() : PersistentExpressionState(eKindGo)
{
}

ConstString
GoPersistentExpressionState::GetNextPersistentVariableName()
{
    char name_cstr[256];
    // We can't use the same variable format as clang.
    ::snprintf(name_cstr, sizeof(name_cstr), "$go%u", m_next_persistent_variable_id++);
    ConstString name(name_cstr);
    return name;
}

void
GoPersistentExpressionState::RemovePersistentVariable(lldb::ExpressionVariableSP variable)
{
    RemoveVariable(variable);

    const char *name = variable->GetName().AsCString();

    if (*(name++) != '$')
        return;
    if (*(name++) != 'g')
        return;
    if (*(name++) != 'o')
        return;

    if (strtoul(name, nullptr, 0) == m_next_persistent_variable_id - 1)
        m_next_persistent_variable_id--;
}
