//===-- Lua.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 "Lua.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Utility/FileSpec.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FormatVariadic.h"

using namespace lldb_private;
using namespace lldb;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"

// Disable warning C4190: 'LLDBSwigPythonBreakpointCallbackFunction' has
// C-linkage specified, but returns UDT 'llvm::Expected<bool>' which is
// incompatible with C
#if _MSC_VER
#pragma warning (push)
#pragma warning (disable : 4190)
#endif

extern "C" llvm::Expected<bool> LLDBSwigLuaBreakpointCallbackFunction(
    lua_State *L, lldb::StackFrameSP stop_frame_sp,
    lldb::BreakpointLocationSP bp_loc_sp, StructuredDataImpl *extra_args_impl);

#if _MSC_VER
#pragma warning (pop)
#endif

#pragma clang diagnostic pop

static int lldb_print(lua_State *L) {
  int n = lua_gettop(L);
  lua_getglobal(L, "io");
  lua_getfield(L, -1, "stdout");
  lua_getfield(L, -1, "write");
  for (int i = 1; i <= n; i++) {
    lua_pushvalue(L, -1); // write()
    lua_pushvalue(L, -3); // io.stdout
    luaL_tolstring(L, i, nullptr);
    lua_pushstring(L, i != n ? "\t" : "\n");
    lua_call(L, 3, 0);
  }
  return 0;
}

Lua::Lua() : m_lua_state(luaL_newstate()) {
  assert(m_lua_state);
  luaL_openlibs(m_lua_state);
  luaopen_lldb(m_lua_state);
  lua_pushcfunction(m_lua_state, lldb_print);
  lua_setglobal(m_lua_state, "print");
}

Lua::~Lua() {
  assert(m_lua_state);
  lua_close(m_lua_state);
}

llvm::Error Lua::Run(llvm::StringRef buffer) {
  int error =
      luaL_loadbuffer(m_lua_state, buffer.data(), buffer.size(), "buffer") ||
      lua_pcall(m_lua_state, 0, 0, 0);
  if (error == LUA_OK)
    return llvm::Error::success();

  llvm::Error e = llvm::make_error<llvm::StringError>(
      llvm::formatv("{0}\n", lua_tostring(m_lua_state, -1)),
      llvm::inconvertibleErrorCode());
  // Pop error message from the stack.
  lua_pop(m_lua_state, 1);
  return e;
}

llvm::Error Lua::RegisterBreakpointCallback(void *baton, const char *body) {
  lua_pushlightuserdata(m_lua_state, baton);
  const char *fmt_str = "return function(frame, bp_loc, ...) {0} end";
  std::string func_str = llvm::formatv(fmt_str, body).str();
  if (luaL_dostring(m_lua_state, func_str.c_str()) != LUA_OK) {
    llvm::Error e = llvm::make_error<llvm::StringError>(
        llvm::formatv("{0}", lua_tostring(m_lua_state, -1)),
        llvm::inconvertibleErrorCode());
    // Pop error message from the stack.
    lua_pop(m_lua_state, 2);
    return e;
  }
  lua_settable(m_lua_state, LUA_REGISTRYINDEX);
  return llvm::Error::success();
}

llvm::Expected<bool>
Lua::CallBreakpointCallback(void *baton, lldb::StackFrameSP stop_frame_sp,
                            lldb::BreakpointLocationSP bp_loc_sp,
                            StructuredData::ObjectSP extra_args_sp) {

  lua_pushlightuserdata(m_lua_state, baton);
  lua_gettable(m_lua_state, LUA_REGISTRYINDEX);
  auto *extra_args_impl = [&]() -> StructuredDataImpl * {
    if (extra_args_sp == nullptr)
      return nullptr;
    auto *extra_args_impl = new StructuredDataImpl();
    extra_args_impl->SetObjectSP(extra_args_sp);
    return extra_args_impl;
  }();
  return LLDBSwigLuaBreakpointCallbackFunction(m_lua_state, stop_frame_sp,
                                               bp_loc_sp, extra_args_impl);
}

llvm::Error Lua::CheckSyntax(llvm::StringRef buffer) {
  int error =
      luaL_loadbuffer(m_lua_state, buffer.data(), buffer.size(), "buffer");
  if (error == LUA_OK) {
    // Pop buffer
    lua_pop(m_lua_state, 1);
    return llvm::Error::success();
  }

  llvm::Error e = llvm::make_error<llvm::StringError>(
      llvm::formatv("{0}\n", lua_tostring(m_lua_state, -1)),
      llvm::inconvertibleErrorCode());
  // Pop error message from the stack.
  lua_pop(m_lua_state, 1);
  return e;
}

llvm::Error Lua::LoadModule(llvm::StringRef filename) {
  FileSpec file(filename);
  if (!FileSystem::Instance().Exists(file)) {
    return llvm::make_error<llvm::StringError>("invalid path",
                                               llvm::inconvertibleErrorCode());
  }

  ConstString module_extension = file.GetFileNameExtension();
  if (module_extension != ".lua") {
    return llvm::make_error<llvm::StringError>("invalid extension",
                                               llvm::inconvertibleErrorCode());
  }

  int error = luaL_loadfile(m_lua_state, filename.data()) ||
              lua_pcall(m_lua_state, 0, 1, 0);
  if (error != LUA_OK) {
    llvm::Error e = llvm::make_error<llvm::StringError>(
        llvm::formatv("{0}\n", lua_tostring(m_lua_state, -1)),
        llvm::inconvertibleErrorCode());
    // Pop error message from the stack.
    lua_pop(m_lua_state, 1);
    return e;
  }

  ConstString module_name = file.GetFileNameStrippingExtension();
  lua_setglobal(m_lua_state, module_name.GetCString());
  return llvm::Error::success();
}

llvm::Error Lua::ChangeIO(FILE *out, FILE *err) {
  assert(out != nullptr);
  assert(err != nullptr);

  lua_getglobal(m_lua_state, "io");

  lua_getfield(m_lua_state, -1, "stdout");
  if (luaL_Stream *s = static_cast<luaL_Stream *>(
          luaL_testudata(m_lua_state, -1, LUA_FILEHANDLE))) {
    s->f = out;
    lua_pop(m_lua_state, 1);
  } else {
    lua_pop(m_lua_state, 2);
    return llvm::make_error<llvm::StringError>("could not get stdout",
                                               llvm::inconvertibleErrorCode());
  }

  lua_getfield(m_lua_state, -1, "stderr");
  if (luaL_Stream *s = static_cast<luaL_Stream *>(
          luaL_testudata(m_lua_state, -1, LUA_FILEHANDLE))) {
    s->f = out;
    lua_pop(m_lua_state, 1);
  } else {
    lua_pop(m_lua_state, 2);
    return llvm::make_error<llvm::StringError>("could not get stderr",
                                               llvm::inconvertibleErrorCode());
  }

  lua_pop(m_lua_state, 1);
  return llvm::Error::success();
}
