// 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.

#include "flow/embedded_views.h"
#include "pointer_injector_delegate.h"
#define RAPIDJSON_HAS_STDSTRING 1

#include "platform_view.h"

#include <algorithm>
#include <cstring>
#include <limits>
#include <sstream>

#include "flutter/fml/logging.h"
#include "flutter/fml/make_copyable.h"
#include "flutter/lib/ui/window/pointer_data.h"
#include "flutter/lib/ui/window/window.h"
#include "flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h"
#include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_message_codec.h"
#include "third_party/rapidjson/include/rapidjson/document.h"
#include "third_party/rapidjson/include/rapidjson/stringbuffer.h"
#include "third_party/rapidjson/include/rapidjson/writer.h"

#include "logging.h"
#include "runtime/dart/utils/inlines.h"
#include "text_delegate.h"
#include "vsync_waiter.h"

namespace flutter_runner {

static constexpr char kFlutterPlatformChannel[] = "flutter/platform";
static constexpr char kAccessibilityChannel[] = "flutter/accessibility";
static constexpr char kFlutterPlatformViewsChannel[] = "flutter/platform_views";
static constexpr char kFuchsiaShaderWarmupChannel[] = "fuchsia/shader_warmup";

PlatformView::PlatformView(
    bool is_flatland,
    flutter::PlatformView::Delegate& delegate,
    flutter::TaskRunners task_runners,
    fuchsia::ui::views::ViewRef view_ref,
    std::shared_ptr<flutter::ExternalViewEmbedder> external_view_embedder,
    fuchsia::ui::input::ImeServiceHandle ime_service,
    fuchsia::ui::input3::KeyboardHandle keyboard,
    fuchsia::ui::pointer::TouchSourceHandle touch_source,
    fuchsia::ui::pointer::MouseSourceHandle mouse_source,
    fuchsia::ui::views::FocuserHandle focuser,
    fuchsia::ui::views::ViewRefFocusedHandle view_ref_focused,
    fuchsia::ui::pointerinjector::RegistryHandle pointerinjector_registry,
    OnEnableWireframe wireframe_enabled_callback,
    OnUpdateView on_update_view_callback,
    OnCreateSurface on_create_surface_callback,
    OnSemanticsNodeUpdate on_semantics_node_update_callback,
    OnRequestAnnounce on_request_announce_callback,
    OnShaderWarmup on_shader_warmup,
    AwaitVsyncCallback await_vsync_callback,
    AwaitVsyncForSecondaryCallbackCallback
        await_vsync_for_secondary_callback_callback)
    : flutter::PlatformView(delegate, std::move(task_runners)),
      external_view_embedder_(external_view_embedder),
      focus_delegate_(
          std::make_shared<FocusDelegate>(std::move(view_ref_focused),
                                          std::move(focuser))),
      pointer_delegate_(
          std::make_shared<PointerDelegate>(std::move(touch_source),
                                            std::move(mouse_source))),
      wireframe_enabled_callback_(std::move(wireframe_enabled_callback)),
      on_update_view_callback_(std::move(on_update_view_callback)),
      on_create_surface_callback_(std::move(on_create_surface_callback)),
      on_semantics_node_update_callback_(
          std::move(on_semantics_node_update_callback)),
      on_request_announce_callback_(std::move(on_request_announce_callback)),
      on_shader_warmup_(std::move(on_shader_warmup)),
      await_vsync_callback_(await_vsync_callback),
      await_vsync_for_secondary_callback_callback_(
          await_vsync_for_secondary_callback_callback),
      weak_factory_(this) {
  fuchsia::ui::views::ViewRef view_ref_clone;
  fidl::Clone(view_ref, &view_ref_clone);

  text_delegate_ =
      std::make_unique<TextDelegate>(
          std::move(view_ref), std::move(ime_service), std::move(keyboard),
          [weak = weak_factory_.GetWeakPtr()](
              std::unique_ptr<flutter::PlatformMessage> message) {
            if (!weak) {
              FML_LOG(WARNING)
                  << "PlatformView use-after-free attempted. Ignoring.";
            }
            weak->delegate_.OnPlatformViewDispatchPlatformMessage(
                std::move(message));
          });

  // Begin watching for focus changes.
  focus_delegate_->WatchLoop([weak = weak_factory_.GetWeakPtr()](bool focused) {
    if (!weak) {
      FML_LOG(WARNING) << "PlatformView use-after-free attempted. Ignoring.";
      return;
    }

    // Ensure last_text_state_ is set to make sure Flutter actually wants
    // an IME.
    if (focused && weak->text_delegate_->HasTextState()) {
      weak->text_delegate_->ActivateIme();
    } else if (!focused) {
      weak->text_delegate_->DeactivateIme();
    }
  });

  // Begin watching for pointer events.
  pointer_delegate_->WatchLoop([weak = weak_factory_.GetWeakPtr()](
                                   std::vector<flutter::PointerData> events) {
    if (!weak) {
      FML_LOG(WARNING) << "PlatformView use-after-free attempted. Ignoring.";
      return;
    }

    if (events.empty()) {
      return;  // No work, bounce out.
    }

    // If pixel ratio hasn't been set, use a default value of 1.
    const float pixel_ratio = weak->view_pixel_ratio_.value_or(1.f);
    auto packet = std::make_unique<flutter::PointerDataPacket>(events.size());
    for (size_t i = 0; i < events.size(); ++i) {
      auto& event = events[i];
      // Translate logical to physical coordinates, as per
      // flutter::PointerData contract. Done here because pixel ratio comes
      // from the graphics API.
      event.physical_x = event.physical_x * pixel_ratio;
      event.physical_y = event.physical_y * pixel_ratio;
      packet->SetPointerData(i, event);
    }
    weak->DispatchPointerDataPacket(std::move(packet));
  });

  // Configure the pointer injector delegate.
  pointer_injector_delegate_ = std::make_unique<PointerInjectorDelegate>(
      std::move(pointerinjector_registry), std::move(view_ref_clone),
      is_flatland);

  // Finally! Register the native platform message handlers.
  RegisterPlatformMessageHandlers();
}

PlatformView::~PlatformView() = default;

void PlatformView::RegisterPlatformMessageHandlers() {
  platform_message_handlers_[kFlutterPlatformChannel] =
      std::bind(&PlatformView::HandleFlutterPlatformChannelPlatformMessage,
                this, std::placeholders::_1);
  platform_message_handlers_[kTextInputChannel] =
      std::bind(&TextDelegate::HandleFlutterTextInputChannelPlatformMessage,
                text_delegate_.get(), std::placeholders::_1);
  platform_message_handlers_[kAccessibilityChannel] =
      std::bind(&PlatformView::HandleAccessibilityChannelPlatformMessage, this,
                std::placeholders::_1);
  platform_message_handlers_[kFlutterPlatformViewsChannel] =
      std::bind(&PlatformView::HandleFlutterPlatformViewsChannelPlatformMessage,
                this, std::placeholders::_1);
  platform_message_handlers_[kFuchsiaShaderWarmupChannel] =
      std::bind(&HandleFuchsiaShaderWarmupChannelPlatformMessage,
                on_shader_warmup_, std::placeholders::_1);
}

static flutter::PointerData::Change GetChangeFromPointerEventPhase(
    fuchsia::ui::input::PointerEventPhase phase) {
  switch (phase) {
    case fuchsia::ui::input::PointerEventPhase::ADD:
      return flutter::PointerData::Change::kAdd;
    case fuchsia::ui::input::PointerEventPhase::HOVER:
      return flutter::PointerData::Change::kHover;
    case fuchsia::ui::input::PointerEventPhase::DOWN:
      return flutter::PointerData::Change::kDown;
    case fuchsia::ui::input::PointerEventPhase::MOVE:
      return flutter::PointerData::Change::kMove;
    case fuchsia::ui::input::PointerEventPhase::UP:
      return flutter::PointerData::Change::kUp;
    case fuchsia::ui::input::PointerEventPhase::REMOVE:
      return flutter::PointerData::Change::kRemove;
    case fuchsia::ui::input::PointerEventPhase::CANCEL:
      return flutter::PointerData::Change::kCancel;
    default:
      return flutter::PointerData::Change::kCancel;
  }
}

static flutter::PointerData::DeviceKind GetKindFromPointerType(
    fuchsia::ui::input::PointerEventType type) {
  switch (type) {
    case fuchsia::ui::input::PointerEventType::TOUCH:
      return flutter::PointerData::DeviceKind::kTouch;
    case fuchsia::ui::input::PointerEventType::MOUSE:
      return flutter::PointerData::DeviceKind::kMouse;
    default:
      return flutter::PointerData::DeviceKind::kTouch;
  }
}

// TODO(SCN-1278): Remove this.
// Turns two floats (high bits, low bits) into a 64-bit uint.
static trace_flow_id_t PointerTraceHACK(float fa, float fb) {
  uint32_t ia, ib;
  memcpy(&ia, &fa, sizeof(uint32_t));
  memcpy(&ib, &fb, sizeof(uint32_t));
  return (((uint64_t)ia) << 32) | ib;
}

// For certain scenarios that must avoid floating-point drift, compute a
// coordinate that falls within the logical view bounding box.
std::array<float, 2> PlatformView::ClampToViewSpace(const float x,
                                                    const float y) const {
  if (!view_logical_size_.has_value() || !view_logical_origin_.has_value()) {
    return {x, y};  // If we can't do anything, return the original values.
  }

  const auto origin = view_logical_origin_.value();
  const auto size = view_logical_size_.value();
  const float min_x = origin[0];
  const float max_x = origin[0] + size[0];
  const float min_y = origin[1];
  const float max_y = origin[1] + size[1];
  if (min_x <= x && x < max_x && min_y <= y && y < max_y) {
    return {x, y};  // No clamping to perform.
  }

  // View boundary is [min_x, max_x) x [min_y, max_y). Note that min is
  // inclusive, but max is exclusive - so we subtract epsilon.
  const float max_x_inclusive = max_x - std::numeric_limits<float>::epsilon();
  const float max_y_inclusive = max_y - std::numeric_limits<float>::epsilon();
  const float& clamped_x = std::clamp(x, min_x, max_x_inclusive);
  const float& clamped_y = std::clamp(y, min_y, max_y_inclusive);
  FML_LOG(INFO) << "Clamped (" << x << ", " << y << ") to (" << clamped_x
                << ", " << clamped_y << ").";
  return {clamped_x, clamped_y};
}

bool PlatformView::OnHandlePointerEvent(
    const fuchsia::ui::input::PointerEvent& pointer) {
  TRACE_EVENT0("flutter", "PlatformView::OnHandlePointerEvent");

  // TODO(SCN-1278): Use proper trace_id for tracing flow.
  trace_flow_id_t trace_id =
      PointerTraceHACK(pointer.radius_major, pointer.radius_minor);
  TRACE_FLOW_END("input", "dispatch_event_to_client", trace_id);

  const float pixel_ratio =
      view_pixel_ratio_.has_value() ? *view_pixel_ratio_ : 0.f;

  flutter::PointerData pointer_data;
  pointer_data.Clear();
  pointer_data.time_stamp = pointer.event_time / 1000;
  pointer_data.change = GetChangeFromPointerEventPhase(pointer.phase);
  pointer_data.kind = GetKindFromPointerType(pointer.type);
  pointer_data.device = pointer.pointer_id;
  // Pointer events are in logical pixels, so scale to physical.
  pointer_data.physical_x = pointer.x * pixel_ratio;
  pointer_data.physical_y = pointer.y * pixel_ratio;
  // Buttons are single bit values starting with kMousePrimaryButton = 1.
  pointer_data.buttons = static_cast<uint64_t>(pointer.buttons);

  switch (pointer_data.change) {
    case flutter::PointerData::Change::kDown: {
      // Make the pointer start in the view space, despite numerical drift.
      auto clamped_pointer = ClampToViewSpace(pointer.x, pointer.y);
      pointer_data.physical_x = clamped_pointer[0] * pixel_ratio;
      pointer_data.physical_y = clamped_pointer[1] * pixel_ratio;

      down_pointers_.insert(pointer_data.device);
      break;
    }
    case flutter::PointerData::Change::kCancel:
    case flutter::PointerData::Change::kUp:
      down_pointers_.erase(pointer_data.device);
      break;
    case flutter::PointerData::Change::kMove:
      if (down_pointers_.count(pointer_data.device) == 0) {
        pointer_data.change = flutter::PointerData::Change::kHover;
      }
      break;
    case flutter::PointerData::Change::kAdd:
      if (down_pointers_.count(pointer_data.device) != 0) {
        FML_LOG(ERROR) << "Received add event for down pointer.";
      }
      break;
    case flutter::PointerData::Change::kRemove:
      if (down_pointers_.count(pointer_data.device) != 0) {
        FML_LOG(ERROR) << "Received remove event for down pointer.";
      }
      break;
    case flutter::PointerData::Change::kHover:
      if (down_pointers_.count(pointer_data.device) != 0) {
        FML_LOG(ERROR) << "Received hover event for down pointer.";
      }
      break;
    case flutter::PointerData::Change::kPanZoomStart:
    case flutter::PointerData::Change::kPanZoomUpdate:
    case flutter::PointerData::Change::kPanZoomEnd:
      FML_DLOG(ERROR) << "Unexpectedly received pointer pan/zoom event";
      break;
  }

  auto packet = std::make_unique<flutter::PointerDataPacket>(1);
  packet->SetPointerData(0, pointer_data);
  DispatchPointerDataPacket(std::move(packet));
  return true;
}

// |flutter::PlatformView|
std::unique_ptr<flutter::VsyncWaiter> PlatformView::CreateVSyncWaiter() {
  return std::make_unique<flutter_runner::VsyncWaiter>(
      await_vsync_callback_, await_vsync_for_secondary_callback_callback_,
      task_runners_);
}

// |flutter::PlatformView|
std::unique_ptr<flutter::Surface> PlatformView::CreateRenderingSurface() {
  return on_create_surface_callback_ ? on_create_surface_callback_() : nullptr;
}

// |flutter::PlatformView|
std::shared_ptr<flutter::ExternalViewEmbedder>
PlatformView::CreateExternalViewEmbedder() {
  return external_view_embedder_;
}

// |flutter::PlatformView|
void PlatformView::HandlePlatformMessage(
    std::unique_ptr<flutter::PlatformMessage> message) {
  if (!message) {
    return;
  }
  const std::string channel = message->channel();
  auto found = platform_message_handlers_.find(channel);
  if (found == platform_message_handlers_.end()) {
    const bool already_errored = unregistered_channels_.count(channel);
    if (!already_errored) {
      FML_LOG(INFO)
          << "Platform view received message on channel '" << message->channel()
          << "' with no registered handler. An empty response will be "
             "generated. Please implement the native message handler. This "
             "message will appear only once per channel.";
      unregistered_channels_.insert(channel);
    }
    flutter::PlatformView::HandlePlatformMessage(std::move(message));
    return;
  }
  auto response = message->response();
  bool response_handled = found->second(std::move(message));

  // Ensure all responses are completed.
  if (response && !response_handled) {
    // response_handled should be true if the response was completed.
    FML_DCHECK(!response->is_complete());
    response->CompleteEmpty();
  }
}

// |flutter::PlatformView|
void PlatformView::SetSemanticsEnabled(bool enabled) {
  flutter::PlatformView::SetSemanticsEnabled(enabled);
  if (enabled) {
    SetAccessibilityFeatures(static_cast<int32_t>(
        flutter::AccessibilityFeatureFlag::kAccessibleNavigation));
  } else {
    SetAccessibilityFeatures(0);
  }
}

// |flutter::PlatformView|
void PlatformView::UpdateSemantics(
    flutter::SemanticsNodeUpdates update,
    flutter::CustomAccessibilityActionUpdates actions) {
  const float pixel_ratio =
      view_pixel_ratio_.has_value() ? *view_pixel_ratio_ : 0.f;

  on_semantics_node_update_callback_(update, pixel_ratio);
}

// Channel handler for kAccessibilityChannel
bool PlatformView::HandleAccessibilityChannelPlatformMessage(
    std::unique_ptr<flutter::PlatformMessage> message) {
  FML_DCHECK(message->channel() == kAccessibilityChannel);

  const flutter::StandardMessageCodec& standard_message_codec =
      flutter::StandardMessageCodec::GetInstance(nullptr);
  std::unique_ptr<flutter::EncodableValue> decoded =
      standard_message_codec.DecodeMessage(message->data().GetMapping(),
                                           message->data().GetSize());

  flutter::EncodableMap map = std::get<flutter::EncodableMap>(*decoded);
  std::string type =
      std::get<std::string>(map.at(flutter::EncodableValue("type")));
  if (type == "announce") {
    flutter::EncodableMap data_map = std::get<flutter::EncodableMap>(
        map.at(flutter::EncodableValue("data")));
    std::string text =
        std::get<std::string>(data_map.at(flutter::EncodableValue("message")));

    on_request_announce_callback_(text);
  }

  // Complete with an empty response.
  return false;
}

// Channel handler for kFlutterPlatformChannel
bool PlatformView::HandleFlutterPlatformChannelPlatformMessage(
    std::unique_ptr<flutter::PlatformMessage> message) {
  FML_DCHECK(message->channel() == kFlutterPlatformChannel);

  // Fuchsia does not handle any platform messages at this time.

  // Complete with an empty response.
  return false;
}

bool PlatformView::HandleFlutterPlatformViewsChannelPlatformMessage(
    std::unique_ptr<flutter::PlatformMessage> message) {
  FML_DCHECK(message->channel() == kFlutterPlatformViewsChannel);
  const auto& data = message->data();
  rapidjson::Document document;
  document.Parse(reinterpret_cast<const char*>(data.GetMapping()),
                 data.GetSize());
  if (document.HasParseError() || !document.IsObject()) {
    FML_LOG(ERROR) << "Could not parse document";
    return false;
  }
  auto root = document.GetObject();
  auto method_member = root.FindMember("method");
  if (method_member == root.MemberEnd() || !method_member->value.IsString()) {
    return false;
  }
  std::string method(method_member->value.GetString());

  if (method == "View.enableWireframe") {
    auto args_it = root.FindMember("args");
    if (args_it == root.MemberEnd() || !args_it->value.IsObject()) {
      FML_LOG(ERROR) << "No arguments found.";
      return false;
    }
    const auto& args = args_it->value;

    auto enable = args.FindMember("enable");
    if (!enable->value.IsBool()) {
      FML_LOG(ERROR) << "Argument 'enable' is not a bool";
      return false;
    }

    wireframe_enabled_callback_(enable->value.GetBool());
  } else if (method == "View.create") {
    auto args_it = root.FindMember("args");
    if (args_it == root.MemberEnd() || !args_it->value.IsObject()) {
      FML_LOG(ERROR) << "No arguments found.";
      return false;
    }
    const auto& args = args_it->value;

    auto view_id = args.FindMember("viewId");
    if (!view_id->value.IsUint64()) {
      FML_LOG(ERROR) << "Argument 'viewId' is not a int64";
      return false;
    }

    auto hit_testable = args.FindMember("hitTestable");
    if (!hit_testable->value.IsBool()) {
      FML_LOG(ERROR) << "Argument 'hitTestable' is not a bool";
      return false;
    }

    auto focusable = args.FindMember("focusable");
    if (!focusable->value.IsBool()) {
      FML_LOG(ERROR) << "Argument 'focusable' is not a bool";
      return false;
    }

    auto on_view_created = fml::MakeCopyable(
        [platform_task_runner = task_runners_.GetPlatformTaskRunner(),
         message = std::move(message)]() {
          // The client is waiting for view creation. Send an empty response
          // back to signal the view was created.
          if (message->response()) {
            message->response()->Complete(std::make_unique<fml::DataMapping>(
                std::vector<uint8_t>({'[', '0', ']'})));
          }
        });
    OnCreateView(std::move(on_view_created), view_id->value.GetUint64(),
                 hit_testable->value.GetBool(), focusable->value.GetBool());
    return true;
  } else if (method == "View.update") {
    auto args_it = root.FindMember("args");
    if (args_it == root.MemberEnd() || !args_it->value.IsObject()) {
      FML_LOG(ERROR) << "No arguments found.";
      return false;
    }
    const auto& args = args_it->value;

    auto view_id = args.FindMember("viewId");
    if (!view_id->value.IsUint64()) {
      FML_LOG(ERROR) << "Argument 'viewId' is not a int64";
      return false;
    }

    auto hit_testable = args.FindMember("hitTestable");
    if (!hit_testable->value.IsBool()) {
      FML_LOG(ERROR) << "Argument 'hitTestable' is not a bool";
      return false;
    }

    auto focusable = args.FindMember("focusable");
    if (!focusable->value.IsBool()) {
      FML_LOG(ERROR) << "Argument 'focusable' is not a bool";
      return false;
    }

    SkRect view_occlusion_hint_raw = SkRect::MakeEmpty();
    auto view_occlusion_hint = args.FindMember("viewOcclusionHintLTRB");
    if (view_occlusion_hint != args.MemberEnd()) {
      if (view_occlusion_hint->value.IsArray()) {
        const auto& view_occlusion_hint_array =
            view_occlusion_hint->value.GetArray();
        if (view_occlusion_hint_array.Size() == 4) {
          bool parse_error = false;
          for (int i = 0; i < 4; i++) {
            auto& array_val = view_occlusion_hint_array[i];
            if (!array_val.IsDouble()) {
              FML_LOG(ERROR) << "Argument 'viewOcclusionHintLTRB' element " << i
                             << " is not a double";
              parse_error = true;
              break;
            }
          }

          if (!parse_error) {
            view_occlusion_hint_raw =
                SkRect::MakeLTRB(view_occlusion_hint_array[0].GetDouble(),
                                 view_occlusion_hint_array[1].GetDouble(),
                                 view_occlusion_hint_array[2].GetDouble(),
                                 view_occlusion_hint_array[3].GetDouble());
          }
        } else {
          FML_LOG(ERROR)
              << "Argument 'viewOcclusionHintLTRB' expected size 4; got "
              << view_occlusion_hint_array.Size();
        }
      } else {
        FML_LOG(ERROR)
            << "Argument 'viewOcclusionHintLTRB' is not a double array";
      }
    } else {
      FML_LOG(WARNING) << "Argument 'viewOcclusionHintLTRB' is missing";
    }

    on_update_view_callback_(
        view_id->value.GetUint64(), view_occlusion_hint_raw,
        hit_testable->value.GetBool(), focusable->value.GetBool());
    if (message->response()) {
      message->response()->Complete(std::make_unique<fml::DataMapping>(
          std::vector<uint8_t>({'[', '0', ']'})));
      return true;
    }
  } else if (method == "View.dispose") {
    auto args_it = root.FindMember("args");
    if (args_it == root.MemberEnd() || !args_it->value.IsObject()) {
      FML_LOG(ERROR) << "No arguments found.";
      return false;
    }
    const auto& args = args_it->value;

    auto view_id = args.FindMember("viewId");
    if (!view_id->value.IsUint64()) {
      FML_LOG(ERROR) << "Argument 'viewId' is not a int64";
      return false;
    }

    OnDisposeView(view_id->value.GetUint64());
    if (message->response()) {
      message->response()->Complete(std::make_unique<fml::DataMapping>(
          std::vector<uint8_t>({'[', '0', ']'})));
      return true;
    }
  } else if (method.rfind("View.focus", 0) == 0) {
    return focus_delegate_->HandlePlatformMessage(root, message->response());
  } else if (method.rfind(PointerInjectorDelegate::kPointerInjectorMethodPrefix,
                          0) == 0) {
    return pointer_injector_delegate_->HandlePlatformMessage(
        root, message->response());
  } else {
    FML_LOG(ERROR) << "Unknown " << message->channel() << " method " << method;
  }
  // Complete with an empty response by default.
  return false;
}

bool PlatformView::HandleFuchsiaShaderWarmupChannelPlatformMessage(
    OnShaderWarmup on_shader_warmup,
    std::unique_ptr<flutter::PlatformMessage> message) {
  FML_DCHECK(message->channel() == kFuchsiaShaderWarmupChannel);

  if (!on_shader_warmup) {
    FML_LOG(ERROR) << "No shader warmup callback set!";
    std::string result = "[0]";
    message->response()->Complete(
        std::make_unique<fml::DataMapping>(std::vector<uint8_t>(
            (const uint8_t*)result.c_str(),
            (const uint8_t*)result.c_str() + result.length())));
    return true;
  }

  const auto& data = message->data();
  rapidjson::Document document;
  document.Parse(reinterpret_cast<const char*>(data.GetMapping()),
                 data.GetSize());
  if (document.HasParseError() || !document.IsObject()) {
    FML_LOG(ERROR) << "Could not parse document";
    return false;
  }
  auto root = document.GetObject();
  auto method = root.FindMember("method");
  if (method == root.MemberEnd() || !method->value.IsString() ||
      method->value != "WarmupSkps") {
    FML_LOG(ERROR) << "Invalid method name";
    return false;
  }

  auto args_it = root.FindMember("args");
  if (args_it == root.MemberEnd() || !args_it->value.IsObject()) {
    FML_LOG(ERROR) << "No arguments found.";
    return false;
  }

  auto shaders_it = root["args"].FindMember("shaders");
  if (shaders_it == root["args"].MemberEnd() || !shaders_it->value.IsArray()) {
    FML_LOG(ERROR) << "No shaders found.";
    return false;
  }

  auto width_it = root["args"].FindMember("width");
  auto height_it = root["args"].FindMember("height");
  if (width_it == root["args"].MemberEnd() || !width_it->value.IsNumber()) {
    FML_LOG(ERROR) << "Invalid width";
    return false;
  }
  if (height_it == root["args"].MemberEnd() || !height_it->value.IsNumber()) {
    FML_LOG(ERROR) << "Invalid height";
    return false;
  }
  auto width = width_it->value.GetUint64();
  auto height = height_it->value.GetUint64();

  std::vector<std::string> skp_paths;
  const auto& shaders = shaders_it->value;
  for (rapidjson::Value::ConstValueIterator itr = shaders.Begin();
       itr != shaders.End(); ++itr) {
    skp_paths.push_back((*itr).GetString());
  }

  auto completion_callback = [response =
                                  message->response()](uint num_successes) {
    std::ostringstream result_stream;
    result_stream << "[" << num_successes << "]";

    std::string result(result_stream.str());

    response->Complete(std::make_unique<fml::DataMapping>(std::vector<uint8_t>(
        (const uint8_t*)result.c_str(),
        (const uint8_t*)result.c_str() + result.length())));
  };

  on_shader_warmup(skp_paths, completion_callback, width, height);
  // The response has already been completed by us.
  return true;
}

}  // namespace flutter_runner
