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

using namespace lldb_private;
using namespace lldb;

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;
}

LuaState::LuaState() : 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");
}

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

llvm::Error LuaState::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::createStringErrorV("{0}\n", lua_tostring(m_lua_state, -1));
  // Pop error message from the stack.
  lua_pop(m_lua_state, 1);
  return e;
}

llvm::Error LuaState::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::createStringErrorV("{0}", lua_tostring(m_lua_state, -1));
    // 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>
LuaState::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);
  StructuredDataImpl extra_args_impl(std::move(extra_args_sp));
  return lua::SWIGBridge::LLDBSwigLuaBreakpointCallbackFunction(
      m_lua_state, stop_frame_sp, bp_loc_sp, extra_args_impl);
}

llvm::Error LuaState::RegisterWatchpointCallback(void *baton,
                                                 const char *body) {
  lua_pushlightuserdata(m_lua_state, baton);
  const char *fmt_str = "return function(frame, wp, ...) {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::createStringErrorV("{0}", lua_tostring(m_lua_state, -1));
    // 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>
LuaState::CallWatchpointCallback(void *baton, lldb::StackFrameSP stop_frame_sp,
                                 lldb::WatchpointSP wp_sp) {

  lua_pushlightuserdata(m_lua_state, baton);
  lua_gettable(m_lua_state, LUA_REGISTRYINDEX);
  return lua::SWIGBridge::LLDBSwigLuaWatchpointCallbackFunction(
      m_lua_state, stop_frame_sp, wp_sp);
}

llvm::Error LuaState::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::createStringErrorV("{0}\n", lua_tostring(m_lua_state, -1));
  // Pop error message from the stack.
  lua_pop(m_lua_state, 1);
  return e;
}

llvm::Error LuaState::LoadModule(llvm::StringRef filename) {
  const FileSpec file(filename);
  if (!FileSystem::Instance().Exists(file)) {
    return llvm::createStringError("invalid path");
  }

  if (file.GetFileNameExtension() != ".lua") {
    return llvm::createStringError("invalid extension");
  }

  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::createStringErrorV("{0}\n", lua_tostring(m_lua_state, -1));
    // Pop error message from the stack.
    lua_pop(m_lua_state, 1);
    return e;
  }

  const std::string module_name = file.GetFileNameStrippingExtension().str();
  lua_setglobal(m_lua_state, module_name.c_str());
  return llvm::Error::success();
}

llvm::Error LuaState::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::createStringError("could not get stdout");
  }

  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::createStringError("could not get stderr");
  }

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