//===-- 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/StringMap.h"
#include "llvm/ADT/StringRef.h"

// Project includes
#include "GoUserExpression.h"

#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.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/Utility/ConstString.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataEncoder.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.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);

  Status &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;
  Status 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,
                                   llvm::StringRef expr, llvm::StringRef prefix,
                                   lldb::LanguageType language,
                                   ResultType desired_type,
                                   const EvaluateExpressionOptions &options)
    : UserExpression(exe_scope, 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, uint32_t line_offset) {
  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.PutString(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.PutString(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);
  Status 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.PutString(eDiagnosticSeverityError, error_cstr);
    else
      diagnostic_manager.PutString(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("Invalid 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("Invalid 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("Invalid 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(llvm::StringRef(), 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(llvm::StringRef(), 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(bool is_error) {
  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--;
}
