// Copyright 2021 The Verible Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "common/lsp/json-rpc-dispatcher.h"

#include <algorithm>
#include <exception>

#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

using nlohmann::json;

namespace verible {
namespace lsp {
TEST(JsonRpcDispatcherTest, Call_GarbledInputRequest) {
  int write_fun_called = 0;

  // If the input can't even be parsed, it is reported back to the client
  JsonRpcDispatcher dispatcher([&](absl::string_view s) {
    const json j = json::parse(s);
    EXPECT_TRUE(j.find("error") != j.end());
    EXPECT_EQ(j["error"]["code"], JsonRpcDispatcher::kParseError) << s;
    ++write_fun_called;
  });

  dispatcher.DispatchMessage("This is not even close to Json");

  EXPECT_EQ(write_fun_called, 1);  // Complain unparseable input.
  EXPECT_EQ(dispatcher.exception_count(), 1);
}

TEST(JsonRpcDispatcherTest, Call_MissingMethodInRequest) {
  // If the request does not contain a method name, it is malformed.
  int write_fun_called = 0;
  int notification_fun_called = 0;

  JsonRpcDispatcher dispatcher([&](absl::string_view s) {
    const json j = json::parse(s);
    EXPECT_TRUE(j.find("error") != j.end());
    EXPECT_EQ(j["error"]["code"], JsonRpcDispatcher::kMethodNotFound) << s;
    ++write_fun_called;
  });
  dispatcher.AddNotificationHandler(
      "foo", [&](const json &j) { ++notification_fun_called; });

  dispatcher.DispatchMessage(
      R"({"jsonrpc":"2.0","params":{"hello": "world"}})");

  EXPECT_EQ(notification_fun_called, 0);
  EXPECT_EQ(write_fun_called, 1);  // Complain about missing method.
  EXPECT_EQ(dispatcher.exception_count(), 0);
}

TEST(JsonRpcDispatcherTest, CallNotification) {
  int write_fun_called = 0;
  int notification_fun_called = 0;

  JsonRpcDispatcher dispatcher([&](absl::string_view s) {
    std::cerr << s;
    ++write_fun_called;
  });
  const bool registered =
      dispatcher.AddNotificationHandler("foo", [&](const json &j) {
        EXPECT_EQ(j, json::parse(R"({ "hello": "world"})"));
        ++notification_fun_called;
      });
  EXPECT_TRUE(registered);

  // Registration for method with that name only works once.
  EXPECT_FALSE(dispatcher.AddNotificationHandler("foo", [](const json &j) {}));

  dispatcher.DispatchMessage(
      R"({"jsonrpc":"2.0","method":"foo","params":{"hello": "world"}})");

  EXPECT_EQ(notification_fun_called, 1);
  EXPECT_EQ(write_fun_called, 0);  // Notifications don't have responses.
  EXPECT_EQ(dispatcher.exception_count(), 0);
}

TEST(JsonRpcDispatcherTest, CallNotification_NotReportInternalError) {
  int write_fun_called = 0;
  int notification_fun_called = 0;

  JsonRpcDispatcher dispatcher(
      [&](absl::string_view s) { ++write_fun_called; });

  // This method does not complete but throws an exception.
  dispatcher.AddNotificationHandler("foo", [&](const json &j) -> json {
    ++notification_fun_called;
    throw std::runtime_error("Okay, Houston, we've had a problem here");
  });

  dispatcher.DispatchMessage(
      R"({"jsonrpc":"2.0","method":"foo","params":{"hello":"world"}})");

  EXPECT_EQ(notification_fun_called, 1);
  EXPECT_EQ(write_fun_called, 0);  // Notification issues never sent back.
  EXPECT_EQ(dispatcher.exception_count(), 1);
}

TEST(JsonRpcDispatcherTest, CallNotification_MissingMethodImplemented) {
  // A notification whose method is not registered must be silently ignored.
  // No response with error.
  int write_fun_called = 0;

  JsonRpcDispatcher dispatcher([&](absl::string_view s) {  //
    ++write_fun_called;
  });

  dispatcher.DispatchMessage(
      R"({"jsonrpc":"2.0","method":"foo","params":{"hello": "world"}})");

  EXPECT_EQ(write_fun_called, 0);
  EXPECT_EQ(dispatcher.exception_count(), 0);
}

TEST(JsonRpcDispatcherTest, CallRpcHandler) {
  int write_fun_called = 0;
  int rpc_fun_called = 0;

  JsonRpcDispatcher dispatcher([&](absl::string_view s) {
    const json j = json::parse(s);
    EXPECT_EQ(std::string(j["result"]["some"]), "response");
    EXPECT_TRUE(j.find("error") == j.end());
    ++write_fun_called;
  });
  const bool registered =
      dispatcher.AddRequestHandler("foo", [&](const json &j) -> json {
        EXPECT_EQ(j, json::parse(R"({ "hello":"world"})"));
        ++rpc_fun_called;
        return json::parse(R"({ "some": "response"})");
      });
  EXPECT_TRUE(registered);

  // Registration with already registered name should fail.
  EXPECT_FALSE(dispatcher.AddRequestHandler(
      "foo", [](const json &j) -> json { return nullptr; }));

  dispatcher.DispatchMessage(
      R"({"jsonrpc":"2.0","id":1,"method":"foo","params":{"hello":"world"}})");

  EXPECT_EQ(rpc_fun_called, 1);
  EXPECT_EQ(write_fun_called, 1);
  EXPECT_EQ(dispatcher.exception_count(), 0);
}

TEST(JsonRpcDispatcherTest, CallRpcHandler_ReportInternalError) {
  int write_fun_called = 0;
  int rpc_fun_called = 0;

  JsonRpcDispatcher dispatcher([&](absl::string_view s) {
    const json j = json::parse(s);
    EXPECT_TRUE(j.find("error") != j.end());
    EXPECT_EQ(j["error"]["code"], JsonRpcDispatcher::kInternalError) << s;
    ++write_fun_called;
  });

  // This method does not complete but throws an exception.
  dispatcher.AddRequestHandler("foo", [&](const json &j) -> json {
    ++rpc_fun_called;
    throw std::runtime_error("Okay, Houston, we've had a problem here");
  });

  dispatcher.DispatchMessage(
      R"({"jsonrpc":"2.0","id":1,"method":"foo","params":{"hello":"world"}})");

  EXPECT_EQ(rpc_fun_called, 1);
  EXPECT_EQ(write_fun_called, 1);
  EXPECT_EQ(dispatcher.exception_count(), 1);
}

TEST(JsonRpcDispatcherTest, CallRpcHandler_MissingMethodImplemented) {
  int write_fun_called = 0;

  JsonRpcDispatcher dispatcher([&](absl::string_view s) {
    const json j = json::parse(s);
    EXPECT_TRUE(j.find("error") != j.end());
    EXPECT_EQ(j["error"]["code"], JsonRpcDispatcher::kMethodNotFound) << s;
    ++write_fun_called;
  });

  dispatcher.DispatchMessage(
      R"({"jsonrpc":"2.0","id":1,"method":"foo","params":{"hello":"world"}})");

  EXPECT_EQ(write_fun_called, 1);  // Reported error.
  EXPECT_EQ(dispatcher.exception_count(), 0);
}

TEST(JsonRpcDispatcherTest, SendNotificationToClient) {
  int write_fun_called = 0;
  JsonRpcDispatcher dispatcher([&](absl::string_view s) {
    const json j = json::parse(s);
    EXPECT_EQ(j["method"], "greeting_method");
    EXPECT_EQ(j["params"], "Hi, y'all");
    ++write_fun_called;
  });

  const json params = "Hi, y'all";
  dispatcher.SendNotification("greeting_method", params);
  EXPECT_EQ(1, write_fun_called);
}
}  // namespace lsp
}  // namespace verible
