//===-- 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/lldb-private.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/ExpressionVariable.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/GoASTContext.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 "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;
    uint32_t num_matches = target->GetImages().FindTypes(sc, name, false, 2, 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(Stream &error_stream, 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])
        error_stream.Printf("error: %s\n", error_cstr);
    else
        error_stream.Printf("error: expression can't be interpreted or run\n");
    return false;
}

lldb::ExpressionResults
GoUserExpression::Execute(Stream &error_stream, 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 ==");

            error_stream.Printf("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])
            error_stream.Printf("error: %s\n", error_cstr);
        else
            error_stream.Printf("error: expression can't be interpreted or run\n");
        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--;
}
