// 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 "fidl.h"

#include <array>
#include <filesystem>
#include <fstream>
#include <iterator>
#include <memory>
#include <set>
#include <vector>

#include "lib/fidl/txn_header.h"
#include "src/developer/shell/josh/lib/object_converter.h"
#include "src/developer/shell/josh/lib/qjs_util.h"
#include "src/developer/shell/josh/lib/zx.h"
#include "src/lib/fidl_codec/encoder.h"
#include "src/lib/fidl_codec/library_loader.h"
#include "src/lib/fidl_codec/wire_parser.h"
#include "third_party/quickjs/quickjs.h"
#include "third_party/rapidjson/include/rapidjson/stringbuffer.h"
#include "third_party/rapidjson/include/rapidjson/writer.h"

namespace shell::fidl {

// TODO(jeremymanson): Dedup from fidl_codec.
namespace {

std::string DocumentToString(rapidjson::Document* document) {
  rapidjson::StringBuffer output;
  rapidjson::Writer<rapidjson::StringBuffer> writer(output);
  document->Accept(writer);
  return output.GetString();
}

JSClassID fidl_class_id_;

JSClassDef fidl_class_ = {
    .class_name = "FidlInternal",
    .finalizer = nullptr,
};

// Loads a FIDL library.
// argv[0] A string name of the library (e.g., "fuchsia.io")
// Returns a boolean indicating success.
JSValue LoadLibrary(JSContext* ctx, JSValueConst this_val, int argc, JSValueConst* argv) {
  if (argc != 1) {
    return JS_ThrowSyntaxError(ctx,
                               "Wrong number of arguments to fidl.loadLibrary(), "
                               "was %d, expected 1",
                               argc);
  }
  auto loader =
      reinterpret_cast<fidl_codec::LibraryLoader*>(JS_GetOpaque(this_val, fidl_class_id_));
  if (loader == nullptr) {
    return JS_EXCEPTION;
  }

  CStringHolder val(ctx, argv[0]);
  const char* path = val.get();
  if (!path) {
    return JS_EXCEPTION;
  }
  fidl_codec::LibraryReadError loader_err;
  loader->AddPath(std::string(path), &loader_err);

  return JS_NewBool(ctx, loader_err.value == fidl_codec::LibraryReadError::kOk);
}

// Loads a FIDL library from a string containing its JSON.
// argv[0] A string name of the library (e.g., "fuchsia.io")
// argv[1] A string containing the IR of the library.
// Returns a boolean indicating success.
JSValue LoadLibraryFromString(JSContext* ctx, JSValueConst this_val, int argc, JSValueConst* argv) {
  if (argc != 2) {
    return JS_ThrowSyntaxError(ctx,
                               "Wrong number of arguments to fidl.loadLibraryFromString(), "
                               "was %d, expected 2",
                               argc);
  }
  auto loader =
      reinterpret_cast<fidl_codec::LibraryLoader*>(JS_GetOpaque(this_val, fidl_class_id_));
  if (loader == nullptr) {
    return JS_EXCEPTION;
  }

  CStringHolder val(ctx, argv[0]);
  const char* path = val.get();
  if (!path) {
    return JS_EXCEPTION;
  }
  fidl_codec::LibraryReadError loader_err;
  CStringHolder contents(ctx, argv[1]);
  loader->AddContent(std::string(contents.get()), &loader_err);

  return JS_NewBool(ctx, loader_err.value == fidl_codec::LibraryReadError::kOk);
}

// Returns an object with a "bytes" and "handles" field containing the encoded version of a fidl
// request.
// argv[0] = Transaction ID.
// argv[1] = Ordinal.
// argv[2] = Object.
JSValue EncodeRequest(JSContext* ctx, JSValueConst this_val, int argc, JSValueConst* argv) {
  const uint8_t kFidlMagic = 1;
  const uint8_t kFlags[3] = {0, 0, 0};

  if (argc != 3) {
    return JS_ThrowSyntaxError(ctx,
                               "Wrong number of arguments to fidl.encodeRequest(), "
                               "was %d, expected 3",
                               argc);
  }
  auto loader =
      reinterpret_cast<fidl_codec::LibraryLoader*>(JS_GetOpaque(this_val, fidl_class_id_));
  if (loader == nullptr) {
    return JS_EXCEPTION;
  }

  int32_t txn_id_signed;
  if (JS_ToInt32(ctx, &txn_id_signed, argv[0]) == -1) {
    return JS_EXCEPTION;
  }
  auto txn_id = static_cast<uint32_t>(txn_id_signed);

  int64_t ordinal_signed;
  if (JS_ToBigInt64(ctx, &ordinal_signed, argv[1]) == -1) {
    return JS_EXCEPTION;
  }
  auto ordinal = static_cast<fidl_codec::Ordinal64>(ordinal_signed);

  const std::vector<const fidl_codec::InterfaceMethod*>* methods = loader->GetByOrdinal(ordinal);

  if (!methods || methods->empty()) {
    return JS_ThrowInternalError(ctx, "Method not found for ordinal %zu", ordinal);
  }

  auto method = (*methods)[0];
  auto request = method->request();
  if (request == nullptr) {
    return JS_ThrowInternalError(ctx, "Method missing request.");
  }

  auto ast = ObjectConverter::Convert(ctx, request, argv[2]);

  if (!ast || !ast->AsStructValue()) {
    return JS_EXCEPTION;
  }

  auto result = fidl_codec::Encoder::EncodeMessage(txn_id, ordinal, kFlags, kFidlMagic,
                                                   *ast->AsStructValue());

  auto bytes = JS_NewArrayBufferCopy(ctx, result.bytes.data(), result.bytes.size());
  auto handles = JS_NewArray(ctx);
  JS_SetPropertyStr(ctx, handles, "length",
                    JS_NewInt32(ctx, static_cast<int32_t>(result.handles.size())));

  for (uint32_t i = 0; i < result.handles.size(); i++) {
    JSValue opaque_handle = zx::HandleCreate(ctx, result.handles[i].handle, result.handles[i].type);
    JSValue user_handle = JS_NewObject(ctx);
    JS_SetPropertyStr(ctx, user_handle, "_handle", opaque_handle);
    JS_SetPropertyUint32(ctx, handles, i, user_handle);
  }

  auto ret = JS_NewObject(ctx);
  JS_SetPropertyStr(ctx, ret, "bytes", bytes);
  JS_SetPropertyStr(ctx, ret, "handles", handles);
  return ret;
}

// Returns a string with the JSON representation of this FIDL message.
// argv[0] = bytes
// argv[1] = handles
JSValue DecodeResponse(JSContext* ctx, JSValueConst this_val, int argc, JSValueConst* argv) {
  if (argc != 2) {
    return JS_ThrowSyntaxError(ctx,
                               "Wrong number of arguments to fidl.decodeResponse(), "
                               "was %d, expected 2",
                               argc);
  }
  auto loader =
      reinterpret_cast<fidl_codec::LibraryLoader*>(JS_GetOpaque(this_val, fidl_class_id_));
  if (loader == nullptr) {
    return JS_EXCEPTION;
  }

  size_t message_len;
  uint8_t* message_buf = JS_GetArrayBuffer(ctx, &message_len, argv[0]);
  if (message_buf == nullptr || message_len < sizeof(fidl_message_header_t)) {
    return JS_NewString(ctx, "");
  }

  if (!JS_IsArray(ctx, argv[1])) {
    return JS_ThrowSyntaxError(ctx, "Expected array of handles");
  }
  int32_t handles_len;
  // It's an array, so assume this works...
  JS_ToInt32(ctx, &handles_len, JS_GetPropertyStr(ctx, argv[1], "length"));
  std::array<zx_handle_disposition_t, ZX_CHANNEL_MAX_MSG_HANDLES> handle_buf;
  // Check if handles returned anything useful.
  for (int32_t i = 0; i < handles_len; i++) {
    JSValue val = JS_GetPropertyUint32(ctx, argv[1], i);
    handle_buf[i] = zx::HandleFromJsval(val);
  }

  auto header = reinterpret_cast<const fidl_message_header_t*>(message_buf);
  const std::vector<const fidl_codec::InterfaceMethod*>* methods =
      loader->GetByOrdinal(header->ordinal);
  // Test method not found, but...
  const fidl_codec::InterfaceMethod* method = (*methods)[0];
  std::unique_ptr<fidl_codec::StructValue> object;
  std::ostringstream errors;
  if (!fidl_codec::DecodeResponse(method, message_buf, message_len, handle_buf.data(), handles_len,
                                  &object, errors)) {
    return JS_ThrowTypeError(ctx, "%s", errors.str().c_str());
  }
  rapidjson::Document actual_response;
  if (object != nullptr) {
    object->ExtractJson(actual_response.GetAllocator(), actual_response);
    std::string val = DocumentToString(&actual_response);
    return JS_NewString(ctx, val.c_str());
  }

  return JS_NewString(ctx, "");
}

// Returns a new library object, which hides a fidl_codec::LibraryLoader.
JSValue NewLibrary(JSContext* ctx, JSValueConst /*this_val*/, int argc, JSValueConst* /*argv*/) {
  if (argc != 0) {
    return JS_ThrowSyntaxError(ctx,
                               "Wrong number of arguments to fidl.decodeResponse(), "
                               "was %d, expected 0",
                               argc);
  }
  JSValue new_library = JS_NewObjectClass(ctx, fidl_class_id_);
  if (JS_IsException(new_library)) {
    return JS_EXCEPTION;
  }
  JS_SetOpaque(new_library, new fidl_codec::LibraryLoader());
  return new_library;
}

// Closes the library passed in via this_val.
JSValue Close(JSContext* ctx, JSValueConst this_val, int argc, JSValueConst* /*argv*/) {
  if (argc != 0) {
    return JS_ThrowSyntaxError(ctx,
                               "Wrong number of arguments to fidl.decodeResponse(), "
                               "was %d, expected 0",
                               argc);
  }
  auto loader =
      reinterpret_cast<fidl_codec::LibraryLoader*>(JS_GetOpaque(this_val, fidl_class_id_));
  if (loader == nullptr) {
    return JS_EXCEPTION;
  }
  delete loader;
  JS_SetOpaque(this_val, nullptr);
  return JS_UNDEFINED;
}

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wc99-designator"
const JSCFunctionListEntry fidl_proto_funcs_[] = {
    JS_CFUNC_DEF("loadLibrary", 1, LoadLibrary),
    JS_CFUNC_DEF("loadLibraryFromString", 1, LoadLibraryFromString),
    JS_CFUNC_DEF("encodeRequest", 1, EncodeRequest),
    JS_CFUNC_DEF("decodeResponse", 1, DecodeResponse),
    JS_CFUNC_DEF("close", 1, Close),
};

JSCFunctionListEntry module_funcs_[] = {JS_CFUNC_DEF("newLibrary", 1, NewLibrary),
                                        JS_PROP_STRING_DEF("irPath", "", JS_PROP_CONFIGURABLE)};
#pragma GCC diagnostic pop

int FidlRunOnInit(JSContext* ctx, JSModuleDef* m) {
  JS_NewClassID(&fidl_class_id_);
  JS_NewClass(JS_GetRuntime(ctx), fidl_class_id_, &fidl_class_);
  JSValue proto = JS_NewObject(ctx);
  JS_SetPropertyFunctionList(ctx, proto, fidl_proto_funcs_, std::size(fidl_proto_funcs_));
  JS_SetClassProto(ctx, fidl_class_id_, proto);
  JS_SetModuleExportList(ctx, m, module_funcs_, std::size(module_funcs_));
  return 0;
};

}  // namespace

JSModuleDef* FidlModuleInit(JSContext* ctx, const char* module_name, const std::string& fidl_path) {
  JSModuleDef* m = JS_NewCModule(ctx, module_name, FidlRunOnInit);
  if (!m) {
    return nullptr;
  }
  module_funcs_[1].u.str = fidl_path.c_str();
  JS_AddModuleExportList(ctx, m, module_funcs_, std::size(module_funcs_));
  return m;
}

}  // namespace shell::fidl
