//===-- FormatterBytecode.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/DataFormatters/FormatterBytecode.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/ValueObject/ValueObjectConstResult.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormatProviders.h"
#include "llvm/Support/FormatVariadicDetails.h"

using namespace lldb;
namespace lldb_private {

std::string toString(FormatterBytecode::OpCodes op) {
  switch (op) {
#define DEFINE_OPCODE(OP, MNEMONIC, NAME)                                      \
  case OP: {                                                                   \
    const char *s = MNEMONIC;                                                  \
    return s ? s : #NAME;                                                      \
  }
#include "lldb/DataFormatters/FormatterBytecode.def"
#undef DEFINE_OPCODE
  }
  return llvm::utostr(op);
}

std::string toString(FormatterBytecode::Selectors sel) {
  switch (sel) {
#define DEFINE_SELECTOR(ID, NAME)                                              \
  case ID:                                                                     \
    return "@" #NAME;
#include "lldb/DataFormatters/FormatterBytecode.def"
#undef DEFINE_SELECTOR
  }
  return "@" + llvm::utostr(sel);
}

std::string toString(FormatterBytecode::Signatures sig) {
  switch (sig) {
#define DEFINE_SIGNATURE(ID, NAME)                                             \
  case ID:                                                                     \
    return "@" #NAME;
#include "lldb/DataFormatters/FormatterBytecode.def"
#undef DEFINE_SIGNATURE
  }
  return llvm::utostr(sig);
}

std::string toString(const FormatterBytecode::DataStack &data) {
  std::string s;
  llvm::raw_string_ostream os(s);
  os << "[ ";
  for (auto &d : data) {
    if (auto s = std::get_if<std::string>(&d))
      os << '"' << *s << '"';
    else if (auto u = std::get_if<uint64_t>(&d))
      os << *u << 'u';
    else if (auto i = std::get_if<int64_t>(&d))
      os << *i;
    else if (auto valobj = std::get_if<ValueObjectSP>(&d)) {
      if (!valobj->get())
        os << "null";
      else
        os << "object(" << valobj->get()->GetValueAsCString() << ')';
    } else if (auto type = std::get_if<CompilerType>(&d)) {
      os << '(' << type->GetTypeName(true) << ')';
    } else if (auto sel = std::get_if<FormatterBytecode::Selectors>(&d)) {
      os << toString(*sel);
    }
    os << ' ';
  }
  os << ']';
  return s;
}

namespace FormatterBytecode {

/// Implement the @format function.
static llvm::Error FormatImpl(DataStack &data) {
  auto fmt = data.Pop<std::string>();
  auto replacements =
      llvm::formatv_object_base::parseFormatString(fmt, 0, false);
  std::string s;
  llvm::raw_string_ostream os(s);
  unsigned num_args = 0;
  for (const auto &r : replacements)
    if (r.Type == llvm::ReplacementType::Format)
      num_args = std::max(num_args, r.Index + 1);

  if (data.size() < num_args)
    return llvm::createStringError("not enough arguments");

  for (const auto &r : replacements) {
    if (r.Type == llvm::ReplacementType::Literal) {
      os << r.Spec;
      continue;
    }
    using namespace llvm::support::detail;
    auto arg = data[data.size() - num_args + r.Index];
    auto format = [&](format_adapter &&adapter) {
      llvm::FmtAlign Align(adapter, r.Where, r.Width, r.Pad);
      Align.format(os, r.Options);
    };

    if (auto s = std::get_if<std::string>(&arg))
      format(build_format_adapter(s->c_str()));
    else if (auto u = std::get_if<uint64_t>(&arg))
      format(build_format_adapter(u));
    else if (auto i = std::get_if<int64_t>(&arg))
      format(build_format_adapter(i));
    else if (auto valobj = std::get_if<ValueObjectSP>(&arg)) {
      if (!valobj->get())
        format(build_format_adapter("null object"));
      else
        format(build_format_adapter(valobj->get()->GetValueAsCString()));
    } else if (auto type = std::get_if<CompilerType>(&arg))
      format(build_format_adapter(type->GetDisplayTypeName()));
    else if (auto sel = std::get_if<FormatterBytecode::Selectors>(&arg))
      format(build_format_adapter(toString(*sel)));
  }
  data.Push(s);
  return llvm::Error::success();
}

static llvm::Error TypeCheck(llvm::ArrayRef<DataStackElement> data,
                             DataType type) {
  if (data.size() < 1)
    return llvm::createStringError("not enough elements on data stack");

  auto &elem = data.back();
  switch (type) {
  case Any:
    break;
  case String:
    if (!std::holds_alternative<std::string>(elem))
      return llvm::createStringError("expected String");
    break;
  case UInt:
    if (!std::holds_alternative<uint64_t>(elem))
      return llvm::createStringError("expected UInt");
    break;
  case Int:
    if (!std::holds_alternative<int64_t>(elem))
      return llvm::createStringError("expected Int");
    break;
  case Object:
    if (!std::holds_alternative<ValueObjectSP>(elem))
      return llvm::createStringError("expected Object");
    break;
  case Type:
    if (!std::holds_alternative<CompilerType>(elem))
      return llvm::createStringError("expected Type");
    break;
  case Selector:
    if (!std::holds_alternative<Selectors>(elem))
      return llvm::createStringError("expected Selector");
    break;
  }
  return llvm::Error::success();
}

static llvm::Error TypeCheck(llvm::ArrayRef<DataStackElement> data,
                             DataType type1, DataType type2) {
  if (auto error = TypeCheck(data, type2))
    return error;
  return TypeCheck(data.drop_back(), type1);
}

static llvm::Error TypeCheck(llvm::ArrayRef<DataStackElement> data,
                             DataType type1, DataType type2, DataType type3) {
  if (auto error = TypeCheck(data, type3))
    return error;
  return TypeCheck(data.drop_back(1), type2, type1);
}

llvm::Error Interpret(ControlStack &control, DataStack &data, Signatures sig) {
  if (control.empty())
    return llvm::Error::success();
  // Since the only data types are single endian and ULEBs, the
  // endianness should not matter.
  llvm::DataExtractor cur_block(control.back(), true);
  llvm::DataExtractor::Cursor pc(0);

  while (!control.empty()) {
    /// Activate the top most block from the control stack.
    auto activate_block = [&]() {
      // Save the return address.
      if (control.size() > 1)
        control[control.size() - 2] = cur_block.getData().drop_front(pc.tell());
      cur_block = llvm::DataExtractor(control.back(), true);
      if (pc)
        pc = llvm::DataExtractor::Cursor(0);
    };

    /// Fetch the next byte in the instruction stream.
    auto next_byte = [&]() -> uint8_t {
      // At the end of the current block?
      while (pc.tell() >= cur_block.size() && !control.empty()) {
        if (control.size() == 1) {
          control.pop_back();
          return 0;
        }
        control.pop_back();
        activate_block();
      }

      // Fetch the next instruction.
      return cur_block.getU8(pc);
    };

    // Fetch the next opcode.
    OpCodes opcode = (OpCodes)next_byte();
    if (control.empty() || !pc)
      return pc.takeError();

    LLDB_LOG_VERBOSE(GetLog(LLDBLog::DataFormatters),
                     "[eval {0}] opcode={1}, control={2}, data={3}",
                     toString(sig), toString(opcode), control.size(),
                     toString(data));

    // Various shorthands to improve the readability of error handling.
#define TYPE_CHECK(...)                                                        \
  if (auto error = TypeCheck(data, __VA_ARGS__))                               \
    return error;

    auto error = [&](llvm::Twine msg) {
      return llvm::createStringError(msg + "(opcode=" + toString(opcode) + ")");
    };

    switch (opcode) {
    // Data stack manipulation.
    case op_dup:
      TYPE_CHECK(Any);
      data.Push(data.back());
      continue;
    case op_drop:
      TYPE_CHECK(Any);
      data.pop_back();
      continue;
    case op_pick: {
      TYPE_CHECK(UInt);
      uint64_t idx = data.Pop<uint64_t>();
      if (idx >= data.size())
        return error("index out of bounds");
      data.Push(data[idx]);
      continue;
    }
    case op_over:
      TYPE_CHECK(Any, Any);
      data.Push(data[data.size() - 2]);
      continue;
    case op_swap: {
      TYPE_CHECK(Any, Any);
      auto x = data.PopAny();
      auto y = data.PopAny();
      data.Push(x);
      data.Push(y);
      continue;
    }
    case op_rot: {
      TYPE_CHECK(Any, Any, Any);
      auto z = data.PopAny();
      auto y = data.PopAny();
      auto x = data.PopAny();
      data.Push(z);
      data.Push(x);
      data.Push(y);
      continue;
    }

    // Control stack manipulation.
    case op_begin: {
      uint64_t length = cur_block.getULEB128(pc);
      if (!pc)
        return pc.takeError();
      llvm::StringRef block = cur_block.getBytes(pc, length);
      if (!pc)
        return pc.takeError();
      control.push_back(block);
      continue;
    }
    case op_if:
      TYPE_CHECK(UInt);
      if (data.Pop<uint64_t>() != 0) {
        if (!cur_block.size())
          return error("empty control stack");
        activate_block();
      } else
        control.pop_back();
      continue;
    case op_ifelse:
      TYPE_CHECK(UInt);
      if (cur_block.size() < 2)
        return error("empty control stack");
      if (data.Pop<uint64_t>() == 0)
        control[control.size() - 2] = control.back();
      control.pop_back();
      activate_block();
      continue;
    case op_return:
      control.clear();
      return pc.takeError();

    // Literals.
    case op_lit_uint:
      data.Push(cur_block.getULEB128(pc));
      continue;
    case op_lit_int:
      data.Push(cur_block.getSLEB128(pc));
      continue;
    case op_lit_selector:
      data.Push(Selectors(cur_block.getU8(pc)));
      continue;
    case op_lit_string: {
      uint64_t length = cur_block.getULEB128(pc);
      llvm::StringRef bytes = cur_block.getBytes(pc, length);
      data.Push(bytes.str());
      continue;
    }
    case op_as_uint: {
      TYPE_CHECK(Int);
      uint64_t casted;
      int64_t val = data.Pop<int64_t>();
      memcpy(&casted, &val, sizeof(val));
      data.Push(casted);
      continue;
    }
    case op_as_int: {
      TYPE_CHECK(UInt);
      int64_t casted;
      uint64_t val = data.Pop<uint64_t>();
      memcpy(&casted, &val, sizeof(val));
      data.Push(casted);
      continue;
    }
    case op_is_null: {
      TYPE_CHECK(Object);
      data.Push(data.Pop<ValueObjectSP>() ? (uint64_t)0 : (uint64_t)1);
      continue;
    }

    // Arithmetic, logic, etc.
#define BINOP_IMPL(OP, CHECK_ZERO)                                             \
  {                                                                            \
    TYPE_CHECK(Any, Any);                                                      \
    auto y = data.PopAny();                                                    \
    if (std::holds_alternative<uint64_t>(y)) {                                 \
      if (CHECK_ZERO && !std::get<uint64_t>(y))                                \
        return error(#OP " by zero");                                          \
      TYPE_CHECK(UInt);                                                        \
      data.Push((uint64_t)(data.Pop<uint64_t>() OP std::get<uint64_t>(y)));    \
    } else if (std::holds_alternative<int64_t>(y)) {                           \
      if (CHECK_ZERO && !std::get<int64_t>(y))                                 \
        return error(#OP " by zero");                                          \
      TYPE_CHECK(Int);                                                         \
      data.Push((int64_t)(data.Pop<int64_t>() OP std::get<int64_t>(y)));       \
    } else                                                                     \
      return error("unsupported data types");                                  \
  }
#define BINOP(OP) BINOP_IMPL(OP, false)
#define BINOP_CHECKZERO(OP) BINOP_IMPL(OP, true)
    case op_plus:
      BINOP(+);
      continue;
    case op_minus:
      BINOP(-);
      continue;
    case op_mul:
      BINOP(*);
      continue;
    case op_div:
      BINOP_CHECKZERO(/);
      continue;
    case op_mod:
      BINOP_CHECKZERO(%);
      continue;
    case op_shl:
#define SHIFTOP(OP, LEFT)                                                      \
  {                                                                            \
    TYPE_CHECK(Any, UInt);                                                     \
    uint64_t y = data.Pop<uint64_t>();                                         \
    if (y > 64)                                                                \
      return error("shift out of bounds");                                     \
    if (std::holds_alternative<uint64_t>(data.back())) {                       \
      uint64_t x = data.Pop<uint64_t>();                                       \
      data.Push(x OP y);                                                       \
    } else if (std::holds_alternative<int64_t>(data.back())) {                 \
      int64_t x = data.Pop<int64_t>();                                         \
      if (x < 0 && LEFT)                                                       \
        return error("left shift of negative value");                          \
      if (y > 64)                                                              \
        return error("shift out of bounds");                                   \
      data.Push(x OP y);                                                       \
    } else                                                                     \
      return error("unsupported data types");                                  \
  }
      SHIFTOP(<<, true);
      continue;
    case op_shr:
      SHIFTOP(>>, false);
      continue;
    case op_and:
      BINOP(&);
      continue;
    case op_or:
      BINOP(|);
      continue;
    case op_xor:
      BINOP(^);
      continue;
    case op_not:
      TYPE_CHECK(UInt);
      data.Push(~data.Pop<uint64_t>());
      continue;
    case op_eq:
      BINOP(==);
      continue;
    case op_neq:
      BINOP(!=);
      continue;
    case op_lt:
      BINOP(<);
      continue;
    case op_gt:
      BINOP(>);
      continue;
    case op_le:
      BINOP(<=);
      continue;
    case op_ge:
      BINOP(>=);
      continue;
    case op_call: {
      TYPE_CHECK(Selector);
      Selectors sel = data.Pop<Selectors>();

      // Shorthand to improve readability.
#define POP_VALOBJ(VALOBJ)                                                     \
  auto VALOBJ = data.Pop<ValueObjectSP>();                                     \
  if (!VALOBJ)                                                                 \
    return error("null object");

      auto sel_error = [&](const char *msg) {
        return llvm::createStringError("{0} (opcode={1}, selector={2})", msg,
                                       toString(opcode).c_str(),
                                       toString(sel).c_str());
      };

      switch (sel) {
      case sel_summary: {
        TYPE_CHECK(Object);
        POP_VALOBJ(valobj);
        const char *summary = valobj->GetSummaryAsCString();
        data.Push(summary ? std::string(valobj->GetSummaryAsCString())
                          : std::string());
        break;
      }
      case sel_get_num_children: {
        TYPE_CHECK(Object);
        POP_VALOBJ(valobj);
        auto result = valobj->GetNumChildren();
        if (!result)
          return result.takeError();
        data.Push((uint64_t)*result);
        break;
      }
      case sel_get_child_at_index: {
        TYPE_CHECK(Object, UInt);
        auto index = data.Pop<uint64_t>();
        POP_VALOBJ(valobj);
        data.Push(valobj->GetChildAtIndex(index));
        break;
      }
      case sel_get_child_with_name: {
        TYPE_CHECK(Object, String);
        auto name = data.Pop<std::string>();
        POP_VALOBJ(valobj);
        data.Push(valobj->GetChildMemberWithName(name));
        break;
      }
      case sel_get_child_index: {
        TYPE_CHECK(Object, String);
        auto name = data.Pop<std::string>();
        POP_VALOBJ(valobj);
        if (auto index_or_err = valobj->GetIndexOfChildWithName(name))
          data.Push((uint64_t)*index_or_err);
        else
          return index_or_err.takeError();
        break;
      }
      case sel_get_type: {
        TYPE_CHECK(Object);
        POP_VALOBJ(valobj);
        // FIXME: do we need to control dynamic type resolution?
        data.Push(valobj->GetTypeImpl().GetCompilerType(false));
        break;
      }
      case sel_get_template_argument_type: {
        TYPE_CHECK(Type, UInt);
        auto index = data.Pop<uint64_t>();
        auto type = data.Pop<CompilerType>();
        // FIXME: There is more code in SBType::GetTemplateArgumentType().
        data.Push(type.GetTypeTemplateArgument(index, true));
        break;
      }
      case sel_get_synthetic_value: {
        TYPE_CHECK(Object);
        POP_VALOBJ(valobj);
        data.Push(valobj->GetSyntheticValue());
        break;
      }
      case sel_get_non_synthetic_value: {
        TYPE_CHECK(Object);
        POP_VALOBJ(valobj);
        data.Push(valobj->GetNonSyntheticValue());
        break;
      }
      case sel_get_value: {
        TYPE_CHECK(Object);
        POP_VALOBJ(valobj);
        data.Push(std::string(valobj->GetValueAsCString()));
        break;
      }
      case sel_get_value_as_unsigned: {
        TYPE_CHECK(Object);
        POP_VALOBJ(valobj);
        bool success;
        uint64_t val = valobj->GetValueAsUnsigned(0, &success);
        data.Push(val);
        if (!success)
          return sel_error("failed to get value");
        break;
      }
      case sel_get_value_as_signed: {
        TYPE_CHECK(Object);
        POP_VALOBJ(valobj);
        bool success;
        int64_t val = valobj->GetValueAsSigned(0, &success);
        data.Push(val);
        if (!success)
          return sel_error("failed to get value");
        break;
      }
      case sel_get_value_as_address: {
        TYPE_CHECK(Object);
        POP_VALOBJ(valobj);
        bool success;
        uint64_t addr = valobj->GetValueAsUnsigned(0, &success);
        if (!success)
          return sel_error("failed to get value");
        if (auto process_sp = valobj->GetProcessSP())
          addr = process_sp->FixDataAddress(addr);
        data.Push(addr);
        break;
      }
      case sel_cast: {
        TYPE_CHECK(Object, Type);
        auto type = data.Pop<CompilerType>();
        POP_VALOBJ(valobj);
        data.Push(valobj->Cast(type));
        break;
      }
      case sel_strlen: {
        TYPE_CHECK(String);
        data.Push((uint64_t)data.Pop<std::string>().size());
        break;
      }
      case sel_fmt: {
        TYPE_CHECK(String);
        if (auto error = FormatImpl(data))
          return error;
        break;
      }
      default:
        return sel_error("selector not implemented");
      }
      continue;
    }
    }
    return error("opcode not implemented");
  }
  return pc.takeError();
}
} // namespace FormatterBytecode

} // namespace lldb_private
