// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "li.h"

#include <stdio.h>

#include <iterator>

#include "src/lib/line_input/line_input.h"
#include "third_party/quickjs/list.h"

namespace shell {

namespace {

JSClassID js_repl_class_id;

JSClassDef js_repl_class = {
    "Repl",
    .finalizer = nullptr,
};

// Expects no arguments
JSValue NewRepl(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
  if (argc != 0) {
    return JS_EXCEPTION;
  }
  repl::Repl *repl = new repl::Repl(ctx, "li > ");
  JSValue obj = JS_NewObjectClass(ctx, js_repl_class_id);
  if (JS_IsException(obj)) {
    return obj;
  }
  JS_SetOpaque(obj, repl);
  return obj;
}

// Expects 1 argument: a repl::Repl object
JSValue CloseRepl(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
  if (argc != 1) {
    return JS_EXCEPTION;
  }
  repl::Repl *repl = reinterpret_cast<repl::Repl *>(JS_GetOpaque(argv[0], js_repl_class_id));
  delete repl;
  return JS_NewBool(ctx, true);
}

// Expects 3 arguments: a repl::Repl object, a byte buffer and the number of relevant bytes
// in the byte buffer
JSValue OnInput(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
  if (argc != 3) {
    return JS_EXCEPTION;
  }
  repl::Repl *repl = reinterpret_cast<repl::Repl *>(JS_GetOpaque(argv[0], js_repl_class_id));
  size_t num_bytes;
  uint8_t *bytes = JS_GetArrayBuffer(ctx, &num_bytes, argv[1]);
  if (!bytes) {
    return JS_ThrowTypeError(ctx, "Expected an ArrayBuffer");
  }
  int len;
  if (JS_ToInt32(ctx, &len, argv[2])) {
    return JS_EXCEPTION;
  }
  bool exit_shell = repl->FeedInput(bytes, len);
  return JS_NewBool(ctx, exit_shell);
}

// Expects 1 argument: a repl::Repl object
// evaluates repl->cmd_, and returns an array [error_in_script (boolean), script_result]
JSValue GetAndEvalCmd(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
  if (argc != 1) {
    return JS_EXCEPTION;
  }
  repl::Repl *repl = reinterpret_cast<repl::Repl *>(JS_GetOpaque(argv[0], js_repl_class_id));
  const char *cmd = repl->GetCmd();
  JSValue script_result = JS_Eval(ctx, cmd, strlen(cmd), "<evalScript>", JS_EVAL_TYPE_GLOBAL);
  bool error_in_script = false;
  if (JS_IsException(script_result)) {
    js_std_dump_error(ctx);
    error_in_script = true;
  }
  JSValue result = JS_NewArray(ctx);
  JS_SetPropertyUint32(ctx, result, 0, JS_NewBool(ctx, error_in_script));
  JS_SetPropertyUint32(ctx, result, 1, script_result);
  return result;
}

// Expects 2 argument: a repl::Repl object and a JS object, the result of a script evaluation
// (that is not an error)
JSValue ShowOutput(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
  if (argc != 2) {
    return JS_EXCEPTION;
  }
  repl::Repl *repl = reinterpret_cast<repl::Repl *>(JS_GetOpaque(argv[0], js_repl_class_id));
  const char *output = JS_ToCString(ctx, argv[1]);
  repl->Write(output);
  repl->Write("\n");
  return JS_NewBool(ctx, true);
}

// Expects 1 argument: a repl::Repl object
JSValue ShowPrompt(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
  if (argc != 1) {
    return JS_EXCEPTION;
  }
  repl::Repl *repl = reinterpret_cast<repl::Repl *>(JS_GetOpaque(argv[0], js_repl_class_id));
  repl->ShowPrompt();
  return JS_NewBool(ctx, true);
}

// Expects 1 argument: a repl::Repl object
JSValue GetLine(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
  if (argc != 1) {
    return JS_EXCEPTION;
  }
  repl::Repl *repl = reinterpret_cast<repl::Repl *>(JS_GetOpaque(argv[0], js_repl_class_id));
  return JS_NewString(ctx, repl->GetLine());
}

const JSCFunctionListEntry js_li_funcs[] = {
    JS_CFUNC_DEF("createRepl", 0, NewRepl),    JS_CFUNC_DEF("onInput", 3, OnInput),
    JS_CFUNC_DEF("closeRepl", 1, CloseRepl),   JS_CFUNC_DEF("getAndEvalCmd", 1, GetAndEvalCmd),
    JS_CFUNC_DEF("showPrompt", 1, ShowPrompt), JS_CFUNC_DEF("showOutput", 2, ShowOutput),
    JS_CFUNC_DEF("getLine", 1, GetLine)};

int LiRunOnInit(JSContext *ctx, JSModuleDef *m) {
  /* Repl Input class */
  JS_NewClassID(&js_repl_class_id);
  JS_NewClass(JS_GetRuntime(ctx), js_repl_class_id, &js_repl_class);
  return JS_SetModuleExportList(ctx, m, js_li_funcs, std::size(js_li_funcs));
};

}  // namespace

namespace li {
JSModuleDef *LiModuleInit(JSContext *ctx, const char *module_name) {
  JSModuleDef *m = JS_NewCModule(ctx, module_name, LiRunOnInit);
  if (!m) {
    return nullptr;
  }
  JS_AddModuleExportList(ctx, m, js_li_funcs, std::size(js_li_funcs));
  return m;
}

// Expects one argument: the repl as a JSValue
repl::Repl *GetRepl(JSContext *ctx, JSValueConst repl_js) {
  repl::Repl *repl = reinterpret_cast<repl::Repl *>(JS_GetOpaque(repl_js, js_repl_class_id));
  return repl;
}

}  // namespace li

}  // namespace shell
