// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#define RAPIDJSON_HAS_STDSTRING 1

#include "flutter/runtime/service_protocol.h"

#include <cstring>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

#include "flutter/fml/posix_wrappers.h"
#include "flutter/fml/synchronization/waitable_event.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#include "third_party/dart/runtime/include/dart_tools_api.h"

namespace flutter {

const std::string_view ServiceProtocol::kScreenshotExtensionName =
    "_flutter.screenshot";
const std::string_view ServiceProtocol::kScreenshotSkpExtensionName =
    "_flutter.screenshotSkp";
const std::string_view ServiceProtocol::kRunInViewExtensionName =
    "_flutter.runInView";
const std::string_view ServiceProtocol::kFlushUIThreadTasksExtensionName =
    "_flutter.flushUIThreadTasks";
const std::string_view ServiceProtocol::kSetAssetBundlePathExtensionName =
    "_flutter.setAssetBundlePath";
const std::string_view ServiceProtocol::kGetDisplayRefreshRateExtensionName =
    "_flutter.getDisplayRefreshRate";
const std::string_view ServiceProtocol::kGetSkSLsExtensionName =
    "_flutter.getSkSLs";
const std::string_view
    ServiceProtocol::kEstimateRasterCacheMemoryExtensionName =
        "_flutter.estimateRasterCacheMemory";
const std::string_view
    ServiceProtocol::kRenderFrameWithRasterStatsExtensionName =
        "_flutter.renderFrameWithRasterStats";

static constexpr std::string_view kViewIdPrefx = "_flutterView/";
static constexpr std::string_view kListViewsExtensionName =
    "_flutter.listViews";

ServiceProtocol::ServiceProtocol()
    : endpoints_({
          // Private
          kListViewsExtensionName,

          // Public
          kScreenshotExtensionName,
          kScreenshotSkpExtensionName,
          kRunInViewExtensionName,
          kFlushUIThreadTasksExtensionName,
          kSetAssetBundlePathExtensionName,
          kGetDisplayRefreshRateExtensionName,
          kGetSkSLsExtensionName,
          kEstimateRasterCacheMemoryExtensionName,
          kRenderFrameWithRasterStatsExtensionName,
      }),
      handlers_mutex_(fml::SharedMutex::Create()) {}

ServiceProtocol::~ServiceProtocol() {
  ToggleHooks(false);
}

void ServiceProtocol::AddHandler(Handler* handler,
                                 Handler::Description description) {
  fml::UniqueLock lock(*handlers_mutex_);
  handlers_.emplace(handler, description);
}

void ServiceProtocol::RemoveHandler(Handler* handler) {
  fml::UniqueLock lock(*handlers_mutex_);
  handlers_.erase(handler);
}

void ServiceProtocol::SetHandlerDescription(Handler* handler,
                                            Handler::Description description) {
  fml::SharedLock lock(*handlers_mutex_);
  auto it = handlers_.find(handler);
  if (it != handlers_.end()) {
    it->second.Store(description);
  }
}

void ServiceProtocol::ToggleHooks(bool set) {
  for (const auto& endpoint : endpoints_) {
    Dart_RegisterIsolateServiceRequestCallback(
        endpoint.data(),                  // method
        &ServiceProtocol::HandleMessage,  // callback
        set ? this : nullptr              // user data
    );
  }
}

static void WriteServerErrorResponse(rapidjson::Document* document,
                                     const char* message) {
  document->SetObject();
  document->AddMember("code", -32000, document->GetAllocator());
  rapidjson::Value message_value;
  message_value.SetString(message, document->GetAllocator());
  document->AddMember("message", message_value, document->GetAllocator());
}

bool ServiceProtocol::HandleMessage(const char* method,
                                    const char** param_keys,
                                    const char** param_values,
                                    intptr_t num_params,
                                    void* user_data,
                                    const char** json_object) {
  Handler::ServiceProtocolMap params;
  for (intptr_t i = 0; i < num_params; i++) {
    params[std::string_view{param_keys[i]}] = std::string_view{param_values[i]};
  }

#ifndef NDEBUG
  FML_DLOG(INFO) << "Service protcol method: " << method;
  FML_DLOG(INFO) << "Arguments: " << params.size();
  for (intptr_t i = 0; i < num_params; i++) {
    FML_DLOG(INFO) << "  " << i + 1 << ": " << param_keys[i] << " = "
                   << param_values[i];
  }
#endif  // NDEBUG

  rapidjson::Document document;
  bool result = HandleMessage(std::string_view{method},                  //
                              params,                                    //
                              static_cast<ServiceProtocol*>(user_data),  //
                              &document                                  //
  );
  rapidjson::StringBuffer buffer;
  rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
  document.Accept(writer);
  *json_object = fml::strdup(buffer.GetString());

#ifndef NDEBUG
  FML_DLOG(INFO) << "Response: " << *json_object;
  FML_DLOG(INFO) << "RPC Result: " << result;
#endif  // NDEBUG

  return result;
}

bool ServiceProtocol::HandleMessage(std::string_view method,
                                    const Handler::ServiceProtocolMap& params,
                                    ServiceProtocol* service_protocol,
                                    rapidjson::Document* response) {
  if (service_protocol == nullptr) {
    WriteServerErrorResponse(response, "Service protocol unavailable.");
    return false;
  }

  return service_protocol->HandleMessage(method, params, response);
}

[[nodiscard]] static bool HandleMessageOnHandler(
    ServiceProtocol::Handler* handler,
    std::string_view method,
    const ServiceProtocol::Handler::ServiceProtocolMap& params,
    rapidjson::Document* document) {
  FML_DCHECK(handler);
  fml::AutoResetWaitableEvent latch;
  bool result = false;
  fml::TaskRunner::RunNowOrPostTask(
      handler->GetServiceProtocolHandlerTaskRunner(method),
      [&latch,    //
       &result,   //
       &handler,  //
       &method,   //
       &params,   //
       &document  //
  ]() {
        result =
            handler->HandleServiceProtocolMessage(method, params, document);
        latch.Signal();
      });
  latch.Wait();
  return result;
}

bool ServiceProtocol::HandleMessage(std::string_view method,
                                    const Handler::ServiceProtocolMap& params,
                                    rapidjson::Document* response) const {
  if (method == kListViewsExtensionName) {
    // So far, this is the only built-in method that does not forward to the
    // dynamic set of handlers.
    return HandleListViewsMethod(response);
  }

  fml::SharedLock lock(*handlers_mutex_);

  if (handlers_.empty()) {
    WriteServerErrorResponse(response,
                             "There are no running service protocol handlers.");
    return false;
  }

  // Find the handler by its "viewId" in the params.
  auto view_id_param_found = params.find(std::string_view{"viewId"});
  if (view_id_param_found != params.end()) {
    auto* handler = reinterpret_cast<Handler*>(std::stoull(
        view_id_param_found->second.data() + kViewIdPrefx.size(), nullptr, 16));
    auto handler_found = handlers_.find(handler);
    if (handler_found != handlers_.end()) {
      return HandleMessageOnHandler(handler, method, params, response);
    }
  }

  // Handle legacy calls that do not specify a handler in their args.
  // TODO(chinmaygarde): Deprecate these calls in the tools and remove these
  // fallbacks.
  if (method == kScreenshotExtensionName ||
      method == kScreenshotSkpExtensionName ||
      method == kFlushUIThreadTasksExtensionName) {
    return HandleMessageOnHandler(handlers_.begin()->first, method, params,
                                  response);
  }

  WriteServerErrorResponse(
      response,
      "Service protocol could not handle or find a handler for the "
      "requested method.");
  return false;
}

static std::string CreateFlutterViewID(intptr_t handler) {
  std::stringstream stream;
  stream << kViewIdPrefx << "0x" << std::hex << handler;
  return stream.str();
}

static std::string CreateIsolateID(int64_t isolate) {
  std::stringstream stream;
  stream << "isolates/" << isolate;
  return stream.str();
}

void ServiceProtocol::Handler::Description::Write(
    Handler* handler,
    rapidjson::Value& view,
    rapidjson::MemoryPoolAllocator<>& allocator) const {
  view.SetObject();
  view.AddMember("type", "FlutterView", allocator);
  view.AddMember("id", CreateFlutterViewID(reinterpret_cast<intptr_t>(handler)),
                 allocator);
  if (isolate_port != 0) {
    rapidjson::Value isolate(rapidjson::Type::kObjectType);
    {
      isolate.AddMember("type", "@Isolate", allocator);
      isolate.AddMember("fixedId", true, allocator);
      isolate.AddMember("id", CreateIsolateID(isolate_port), allocator);
      isolate.AddMember("name", isolate_name, allocator);
      isolate.AddMember("number", isolate_port, allocator);
    }
    view.AddMember("isolate", isolate, allocator);
  }
}

bool ServiceProtocol::HandleListViewsMethod(
    rapidjson::Document* response) const {
  fml::SharedLock lock(*handlers_mutex_);
  std::vector<std::pair<intptr_t, Handler::Description>> descriptions;
  for (const auto& handler : handlers_) {
    descriptions.emplace_back(reinterpret_cast<intptr_t>(handler.first),
                              handler.second.Load());
  }

  auto& allocator = response->GetAllocator();

  // Construct the response objects.
  response->SetObject();
  response->AddMember("type", "FlutterViewList", allocator);

  rapidjson::Value viewsList(rapidjson::Type::kArrayType);
  for (const auto& description : descriptions) {
    rapidjson::Value view(rapidjson::Type::kObjectType);
    description.second.Write(reinterpret_cast<Handler*>(description.first),
                             view, allocator);
    viewsList.PushBack(view, allocator);
  }

  response->AddMember("views", viewsList, allocator);

  return true;
}

}  // namespace flutter
