// 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 "pointer_injector_delegate.h"
#include "flutter/fml/logging.h"

namespace flutter_runner {

using fup_Config = fuchsia::ui::pointerinjector::Config;
using fup_Context = fuchsia::ui::pointerinjector::Context;
using fup_Data = fuchsia::ui::pointerinjector::Data;
using fup_DeviceType = fuchsia::ui::pointerinjector::DeviceType;
using fup_DispatchPolicy = fuchsia::ui::pointerinjector::DispatchPolicy;
using fup_Event = fuchsia::ui::pointerinjector::Event;
using fup_EventPhase = fuchsia::ui::pointerinjector::EventPhase;
using fup_PointerSample = fuchsia::ui::pointerinjector::PointerSample;
using fup_Target = fuchsia::ui::pointerinjector::Target;
using fup_Viewport = fuchsia::ui::pointerinjector::Viewport;
using fuv_ViewRef = fuchsia::ui::views::ViewRef;
const auto fup_MAX_INJECT = fuchsia::ui::pointerinjector::MAX_INJECT;

namespace {

// clang-format off
  static constexpr std::array<float, 9> kIdentityMatrix = {
    1, 0, 0, // column one
    0, 1, 0, // column two
    0, 0, 1, // column three
  };
// clang-format on

}  // namespace

bool PointerInjectorDelegate::HandlePlatformMessage(
    rapidjson::Value request,
    fml::RefPtr<flutter::PlatformMessageResponse> response) {
  if (!registry_->is_bound()) {
    FML_LOG(WARNING)
        << "Lost connection to fuchsia.ui.pointerinjector.Registry";
    return false;
  }

  auto method = request.FindMember("method");
  if (method == request.MemberEnd() || !method->value.IsString()) {
    return false;
  }

  if (method->value == kPointerInjectorMethodPrefix) {
    auto args_it = request.FindMember("args");
    if (args_it == request.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 uint64";
      return false;
    }
    auto id = view_id->value.GetUint64();

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

    auto pointer_x = args.FindMember("x");
    if (!pointer_x->value.IsFloat() && !pointer_x->value.IsInt()) {
      FML_LOG(ERROR) << "Argument 'Pointer.X' is not a float";
      return false;
    }

    auto pointer_y = args.FindMember("y");
    if (!pointer_y->value.IsFloat() && !pointer_y->value.IsInt()) {
      FML_LOG(ERROR) << "Argument 'Pointer.Y' is not a float";
      return false;
    }

    auto pointer_id = args.FindMember("pointerId");
    if (!pointer_id->value.IsUint()) {
      FML_LOG(ERROR) << "Argument 'pointerId' is not a uint32";
      return false;
    }

    auto trace_flow_id = args.FindMember("traceFlowId");
    if (!trace_flow_id->value.IsInt()) {
      FML_LOG(ERROR) << "Argument 'traceFlowId' is not a int";
      return false;
    }

    // For GFX, the viewRef for the view is provided through the platform
    // message. For flatland, the viewRef is provided through |OnCreateView|.
    std::optional<fuv_ViewRef> view_ref;
    if (!is_flatland_) {
      auto view_ref_arg = args.FindMember("viewRef");
      if (!view_ref_arg->value.IsUint64()) {
        FML_LOG(ERROR) << "Argument 'viewRef' is not a uint64";
        return false;
      }

      zx_handle_t handle = view_ref_arg->value.GetUint64();
      zx_handle_t out_handle;
      zx_status_t status =
          zx_handle_duplicate(handle, ZX_RIGHT_SAME_RIGHTS, &out_handle);
      if (status != ZX_OK) {
        FML_LOG(ERROR) << "Argument 'viewRef' is not valid";
        return false;
      }
      auto ref = fuv_ViewRef({
          .reference = zx::eventpair(out_handle),
      });
      view_ref = std::move(ref);
    }

    auto width = args.FindMember("logicalWidth");
    if (!width->value.IsFloat() && !width->value.IsInt()) {
      FML_LOG(ERROR) << "Argument 'logicalWidth' is not a float";
      return false;
    }

    auto height = args.FindMember("logicalHeight");
    if (!height->value.IsFloat() && !height->value.IsInt()) {
      FML_LOG(ERROR) << "Argument 'logicalHeight' is not a float";
      return false;
    }

    auto timestamp = args.FindMember("timestamp");
    if (!timestamp->value.IsInt() && !timestamp->value.IsUint64()) {
      FML_LOG(ERROR) << "Argument 'timestamp' is not a int";
      return false;
    }

    PointerInjectorRequest request = {
        .x = pointer_x->value.GetFloat(),
        .y = pointer_y->value.GetFloat(),
        .pointer_id = pointer_id->value.GetUint(),
        .phase = static_cast<fup_EventPhase>(phase->value.GetInt()),
        .trace_flow_id = trace_flow_id->value.GetUint64(),
        .view_ref = std::move(view_ref),
        .logical_size = {width->value.GetFloat(), height->value.GetFloat()},
        .timestamp = timestamp->value.GetInt()};

    // Inject the pointer event if the view has been created.
    if (valid_views_.count(id) > 0) {
      valid_views_.at(id).InjectEvent(std::move(request));
      Complete(std::move(response), "[0]");
    } else {
      return false;
    }
  } else {
    return false;
  }
  // All of our methods complete the platform message response.
  return true;
}

void PointerInjectorDelegate::OnCreateView(
    uint64_t view_id,
    std::optional<fuv_ViewRef> view_ref) {
  FML_CHECK(valid_views_.count(view_id) == 0);

  auto [_, success] = valid_views_.try_emplace(
      view_id, registry_, host_view_ref_, std::move(view_ref));

  FML_CHECK(success);
}

fup_Event PointerInjectorDelegate::ExtractPointerEvent(
    PointerInjectorRequest request) {
  fup_Event event;
  event.set_timestamp(request.timestamp);
  event.set_trace_flow_id(request.trace_flow_id);

  fup_PointerSample pointer_sample;
  pointer_sample.set_pointer_id(request.pointer_id);
  pointer_sample.set_phase(request.phase);
  pointer_sample.set_position_in_viewport({request.x, request.y});

  fup_Data data;
  data.set_pointer_sample(std::move(pointer_sample));

  event.set_data(std::move(data));
  return event;
}

void PointerInjectorDelegate::Complete(
    fml::RefPtr<flutter::PlatformMessageResponse> response,
    std::string value) {
  if (response) {
    response->Complete(std::make_unique<fml::DataMapping>(
        std::vector<uint8_t>(value.begin(), value.end())));
  }
}

void PointerInjectorDelegate::PointerInjectorEndpoint::InjectEvent(
    PointerInjectorRequest request) {
  if (!registered_) {
    RegisterInjector(request);
  }

  auto event = ExtractPointerEvent(std::move(request));

  // Add the event to |injector_events_| and dispatch it to the view.
  EnqueueEvent(std::move(event));

  DispatchPendingEvents();
}

void PointerInjectorDelegate::PointerInjectorEndpoint::DispatchPendingEvents() {
  // Return if there is already a |fuchsia.ui.pointerinjector.Device.Inject|
  // call in flight. The new pointer events will be dispatched once the
  // in-progress call terminates.
  if (injection_in_flight_) {
    return;
  }

  // Dispatch the events present in |injector_events_|. Note that we recursively
  // call |DispatchPendingEvents| in the callback passed to the
  // |f.u.p.Device.Inject| call. This ensures that there is only one
  // |f.u.p.Device.Inject| call at a time. If a new pointer event comes when
  // there is a |f.u.p.Device.Inject| call in progress, it gets buffered in
  // |injector_events_| and is picked up later.
  if (!injector_events_.empty()) {
    auto events = std::move(injector_events_.front());
    injector_events_.pop();
    injection_in_flight_ = true;

    FML_CHECK(device_.is_bound());
    FML_CHECK(events.size() <= fup_MAX_INJECT);

    device_->Inject(std::move(events), [weak = weak_factory_.GetWeakPtr()] {
      if (!weak) {
        FML_LOG(WARNING) << "Use after free attempted.";
        return;
      }
      weak->injection_in_flight_ = false;
      weak->DispatchPendingEvents();
    });
  }
}

void PointerInjectorDelegate::PointerInjectorEndpoint::EnqueueEvent(
    fup_Event event) {
  // Add |event| in |injector_events_| keeping in mind that the vector size does
  // not exceed |fup_MAX_INJECT|.
  if (!injector_events_.empty() &&
      injector_events_.back().size() < fup_MAX_INJECT) {
    injector_events_.back().push_back(std::move(event));
  } else {
    std::vector<fup_Event> vec;
    vec.reserve(fup_MAX_INJECT);
    vec.push_back(std::move(event));
    injector_events_.push(std::move(vec));
  }
}

void PointerInjectorDelegate::PointerInjectorEndpoint::RegisterInjector(
    const PointerInjectorRequest& request) {
  if (registered_) {
    return;
  }

  fup_Config config;
  config.set_device_id(1);
  config.set_device_type(fup_DeviceType::TOUCH);
  config.set_dispatch_policy(fup_DispatchPolicy::EXCLUSIVE_TARGET);

  fup_Context context;
  fuv_ViewRef context_clone;
  fidl::Clone(*host_view_ref_, &context_clone);
  context.set_view(std::move(context_clone));
  config.set_context(std::move(context));

  FML_CHECK(request.view_ref.has_value() || view_ref_.has_value());
  fup_Target target;
  fuv_ViewRef target_clone;

  // GFX.
  if (request.view_ref.has_value()) {
    fidl::Clone(*request.view_ref, &target_clone);
  }
  // Flatland.
  else {
    fidl::Clone(*view_ref_, &target_clone);
  }
  target.set_view(std::move(target_clone));
  config.set_target(std::move(target));

  fup_Viewport viewport;
  viewport.set_viewport_to_context_transform(kIdentityMatrix);
  std::array<std::array<float, 2>, 2> extents{
      {/*min*/ {0, 0},
       /*max*/ {request.logical_size[0], request.logical_size[1]}}};
  viewport.set_extents(std::move(extents));
  config.set_viewport(std::move(viewport));

  FML_CHECK(registry_->is_bound());

  (*registry_)->Register(std::move(config), device_.NewRequest(), [] {});

  registered_ = true;
}

}  // namespace flutter_runner
