//===--- XPCTransport.cpp - sending and receiving LSP messages over XPC ---===//
//
// 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 "Conversion.h"
#include "Logger.h"
#include "Protocol.h" // For LSPError
#include "Transport.h"
#include "llvm/Support/Errno.h"

#include <xpc/xpc.h>

using namespace llvm;
using namespace clang;
using namespace clangd;

namespace {

json::Object encodeError(Error E) {
  std::string Message;
  ErrorCode Code = ErrorCode::UnknownErrorCode;
  if (Error Unhandled =
          handleErrors(std::move(E), [&](const LSPError &L) -> Error {
            Message = L.Message;
            Code = L.Code;
            return Error::success();
          }))
    Message = toString(std::move(Unhandled));

  return json::Object{
      {"message", std::move(Message)},
      {"code", int64_t(Code)},
  };
}

Error decodeError(const json::Object &O) {
  std::string Msg = O.getString("message").getValueOr("Unspecified error");
  if (auto Code = O.getInteger("code"))
    return make_error<LSPError>(std::move(Msg), ErrorCode(*Code));
  return make_error<StringError>(std::move(Msg), inconvertibleErrorCode());
}

// C "closure" for XPCTransport::loop() method
namespace xpcClosure {
void connection_handler(xpc_connection_t clientConnection);
}

class XPCTransport : public Transport {
public:
  XPCTransport() {}

  void notify(StringRef Method, json::Value Params) override {
    sendMessage(json::Object{
        {"jsonrpc", "2.0"},
        {"method", Method},
        {"params", std::move(Params)},
    });
  }
  void call(StringRef Method, json::Value Params, json::Value ID) override {
    sendMessage(json::Object{
        {"jsonrpc", "2.0"},
        {"id", std::move(ID)},
        {"method", Method},
        {"params", std::move(Params)},
    });
  }
  void reply(json::Value ID, Expected<json::Value> Result) override {
    if (Result) {
      sendMessage(json::Object{
          {"jsonrpc", "2.0"},
          {"id", std::move(ID)},
          {"result", std::move(*Result)},
      });
    } else {
      sendMessage(json::Object{
          {"jsonrpc", "2.0"},
          {"id", std::move(ID)},
          {"error", encodeError(Result.takeError())},
      });
    }
  }

  Error loop(MessageHandler &Handler) override;

private:
  // Needs access to handleMessage() and resetClientConnection()
  friend void xpcClosure::connection_handler(xpc_connection_t clientConnection);

  // Dispatches incoming message to Handler onNotify/onCall/onReply.
  bool handleMessage(json::Value Message, MessageHandler &Handler);
  void sendMessage(json::Value Message) {
    xpc_object_t response = jsonToXpc(Message);
    xpc_connection_send_message(clientConnection, response);
    xpc_release(response);
  }
  void resetClientConnection(xpc_connection_t newClientConnection) {
    clientConnection = newClientConnection;
  }
  xpc_connection_t clientConnection;
};

bool XPCTransport::handleMessage(json::Value Message, MessageHandler &Handler) {
  // Message must be an object with "jsonrpc":"2.0".
  auto *Object = Message.getAsObject();
  if (!Object || Object->getString("jsonrpc") != Optional<StringRef>("2.0")) {
    elog("Not a JSON-RPC 2.0 message: {0:2}", Message);
    return false;
  }
  // ID may be any JSON value. If absent, this is a notification.
  Optional<json::Value> ID;
  if (auto *I = Object->get("id"))
    ID = std::move(*I);
  auto Method = Object->getString("method");
  if (!Method) { // This is a response.
    if (!ID) {
      elog("No method and no response ID: {0:2}", Message);
      return false;
    }
    if (auto *Err = Object->getObject("error"))
      return Handler.onReply(std::move(*ID), decodeError(*Err));
    // Result should be given, use null if not.
    json::Value Result = nullptr;
    if (auto *R = Object->get("result"))
      Result = std::move(*R);
    return Handler.onReply(std::move(*ID), std::move(Result));
  }
  // Params should be given, use null if not.
  json::Value Params = nullptr;
  if (auto *P = Object->get("params"))
    Params = std::move(*P);

  if (ID)
    return Handler.onCall(*Method, std::move(Params), std::move(*ID));
  else
    return Handler.onNotify(*Method, std::move(Params));
}

namespace xpcClosure {
// "owner" of this "closure object" - necessary for propagating connection to
// XPCTransport so it can send messages to the client.
XPCTransport *TransportObject = nullptr;
Transport::MessageHandler *HandlerPtr = nullptr;

void connection_handler(xpc_connection_t clientConnection) {
  xpc_connection_set_target_queue(clientConnection, dispatch_get_main_queue());

  xpc_transaction_begin();

  TransportObject->resetClientConnection(clientConnection);

  xpc_connection_set_event_handler(clientConnection, ^(xpc_object_t message) {
    if (message == XPC_ERROR_CONNECTION_INVALID) {
      // connection is being terminated
      log("Received XPC_ERROR_CONNECTION_INVALID message - returning from the "
          "event_handler.");
      return;
    }

    if (xpc_get_type(message) != XPC_TYPE_DICTIONARY) {
      log("Received XPC message of unknown type - returning from the "
          "event_handler.");
      return;
    }

    const json::Value Doc = xpcToJson(message);
    if (Doc == json::Value(nullptr)) {
      log("XPC message was converted to Null JSON message - returning from the "
          "event_handler.");
      return;
    }

    vlog("<<< {0}\n", Doc);

    if (!TransportObject->handleMessage(std::move(Doc), *HandlerPtr)) {
      log("Received exit notification - cancelling connection.");
      xpc_connection_cancel(xpc_dictionary_get_remote_connection(message));
      xpc_transaction_end();
    }
  });

  xpc_connection_resume(clientConnection);
}
} // namespace xpcClosure

Error XPCTransport::loop(MessageHandler &Handler) {
  assert(xpcClosure::TransportObject == nullptr &&
         "TransportObject has already been set.");
  // This looks scary since lifetime of this (or any) XPCTransport object has
  // to fully contain lifetime of any XPC connection. In practise any Transport
  // object is destroyed only at the end of main() which is always after
  // exit of xpc_main().
  xpcClosure::TransportObject = this;

  assert(xpcClosure::HandlerPtr == nullptr &&
         "HandlerPtr has already been set.");
  xpcClosure::HandlerPtr = &Handler;

  xpc_main(xpcClosure::connection_handler);
  // xpc_main doesn't ever return
  return errorCodeToError(std::make_error_code(std::errc::io_error));
}

} // namespace

namespace clang {
namespace clangd {

std::unique_ptr<Transport> newXPCTransport() {
  return std::make_unique<XPCTransport>();
}

} // namespace clangd
} // namespace clang
