// 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 "gfx_platform_view.h"

#include "flutter/fml/make_copyable.h"

namespace flutter_runner {

GfxPlatformView::GfxPlatformView(
    flutter::PlatformView::Delegate& delegate,
    flutter::TaskRunners task_runners,
    fuchsia::ui::views::ViewRef view_ref,
    std::shared_ptr<flutter::ExternalViewEmbedder> external_view_embedder,
    fidl::InterfaceHandle<fuchsia::ui::input::ImeService> ime_service,
    fidl::InterfaceHandle<fuchsia::ui::input3::Keyboard> keyboard,
    fidl::InterfaceHandle<fuchsia::ui::pointer::TouchSource> touch_source,
    fidl::InterfaceHandle<fuchsia::ui::pointer::MouseSource> mouse_source,
    fidl::InterfaceHandle<fuchsia::ui::views::Focuser> focuser,
    fidl::InterfaceHandle<fuchsia::ui::views::ViewRefFocused> view_ref_focused,
    fidl::InterfaceRequest<fuchsia::ui::scenic::SessionListener>
        session_listener_request,
    fit::closure on_session_listener_error_callback,
    OnEnableWireframe wireframe_enabled_callback,
    OnCreateGfxView on_create_view_callback,
    OnUpdateView on_update_view_callback,
    OnDestroyGfxView on_destroy_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)
    : PlatformView(delegate,
                   std::move(task_runners),
                   std::move(view_ref),
                   std::move(external_view_embedder),
                   std::move(ime_service),
                   std::move(keyboard),
                   std::move(touch_source),
                   std::move(mouse_source),
                   std::move(focuser),
                   std::move(view_ref_focused),
                   std::move(wireframe_enabled_callback),
                   std::move(on_update_view_callback),
                   std::move(on_create_surface_callback),
                   std::move(on_semantics_node_update_callback),
                   std::move(on_request_announce_callback),
                   std::move(on_shader_warmup),
                   std::move(await_vsync_callback),
                   std::move(await_vsync_for_secondary_callback_callback)),
      session_listener_binding_(this, std::move(session_listener_request)),
      session_listener_error_callback_(
          std::move(on_session_listener_error_callback)),
      on_create_view_callback_(std::move(on_create_view_callback)),
      on_destroy_view_callback_(std::move(on_destroy_view_callback)),
      weak_factory_(this) {
  session_listener_binding_.set_error_handler([](zx_status_t status) {
    FML_LOG(ERROR) << "Interface error on: SessionListener, status: " << status;
  });
}

GfxPlatformView::~GfxPlatformView() = default;

void GfxPlatformView::OnScenicError(std::string error) {
  FML_LOG(ERROR) << "Session error: " << error;
  session_listener_error_callback_();
}

void GfxPlatformView::OnScenicEvent(
    std::vector<fuchsia::ui::scenic::Event> events) {
  TRACE_EVENT0("flutter", "PlatformView::OnScenicEvent");

  std::vector<fuchsia::ui::gfx::Event> deferred_view_events;
  bool metrics_changed = false;
  for (auto& event : events) {
    switch (event.Which()) {
      case fuchsia::ui::scenic::Event::Tag::kGfx:
        switch (event.gfx().Which()) {
          case fuchsia::ui::gfx::Event::Tag::kMetrics: {
            const fuchsia::ui::gfx::Metrics& metrics =
                event.gfx().metrics().metrics;
            const float new_view_pixel_ratio = metrics.scale_x;
            if (new_view_pixel_ratio <= 0.f) {
              FML_DLOG(ERROR)
                  << "Got an invalid pixel ratio from Scenic; ignoring: "
                  << new_view_pixel_ratio;
              break;
            }

            // Avoid metrics update when possible -- it is computationally
            // expensive.
            if (view_pixel_ratio_.has_value() &&
                *view_pixel_ratio_ == new_view_pixel_ratio) {
              FML_DLOG(ERROR)
                  << "Got an identical pixel ratio from Scenic; ignoring: "
                  << new_view_pixel_ratio;
              break;
            }

            view_pixel_ratio_ = new_view_pixel_ratio;
            metrics_changed = true;
            break;
          }
          case fuchsia::ui::gfx::Event::Tag::kViewPropertiesChanged: {
            const fuchsia::ui::gfx::BoundingBox& bounding_box =
                event.gfx().view_properties_changed().properties.bounding_box;
            const std::array<float, 2> new_view_size = {
                std::max(bounding_box.max.x - bounding_box.min.x, 0.0f),
                std::max(bounding_box.max.y - bounding_box.min.y, 0.0f)};
            if (new_view_size[0] <= 0.f || new_view_size[1] <= 0.f) {
              FML_DLOG(ERROR)
                  << "Got an invalid view size from Scenic; ignoring: "
                  << new_view_size[0] << " " << new_view_size[1];
              break;
            }

            // Avoid metrics update when possible -- it is computationally
            // expensive.
            if (view_logical_size_.has_value() &&
                *view_logical_size_ == new_view_size) {
              FML_DLOG(ERROR)
                  << "Got an identical view size from Scenic; ignoring: "
                  << new_view_size[0] << " " << new_view_size[1];
              break;
            }

            view_logical_size_ = new_view_size;
            view_logical_origin_ = {bounding_box.min.x, bounding_box.min.y};
            metrics_changed = true;
            break;
          }
          case fuchsia::ui::gfx::Event::Tag::kViewConnected:
            if (!OnChildViewConnected(
                    event.gfx().view_connected().view_holder_id)) {
              deferred_view_events.push_back(std::move(event.gfx()));
            }
            break;
          case fuchsia::ui::gfx::Event::Tag::kViewDisconnected:
            if (!OnChildViewDisconnected(
                    event.gfx().view_disconnected().view_holder_id)) {
              deferred_view_events.push_back(std::move(event.gfx()));
            }
            break;
          case fuchsia::ui::gfx::Event::Tag::kViewStateChanged:
            if (!OnChildViewStateChanged(
                    event.gfx().view_state_changed().view_holder_id,
                    event.gfx().view_state_changed().state.is_rendering)) {
              deferred_view_events.push_back(std::move(event.gfx()));
            }
            break;
          case fuchsia::ui::gfx::Event::Tag::Invalid:
            FML_DCHECK(false) << "Flutter PlatformView::OnScenicEvent: Got "
                                 "an invalid GFX event.";
            break;
          default:
            // We don't care about some event types, so not handling them is OK.
            break;
        }
        break;
      case fuchsia::ui::scenic::Event::Tag::kInput:
        switch (event.input().Which()) {
          case fuchsia::ui::input::InputEvent::Tag::kFocus:
            break;  // Focus handled elsewhere.
          case fuchsia::ui::input::InputEvent::Tag::kPointer: {
            // Only received when TouchSource not plugged in.
            OnHandlePointerEvent(event.input().pointer());
            break;
          }
          case fuchsia::ui::input::InputEvent::Tag::kKeyboard: {
            // All devices should receive key events via input3.KeyboardListener
            // instead.
            FML_LOG(WARNING) << "Keyboard event from Scenic: ignored";
            break;
          }
          case fuchsia::ui::input::InputEvent::Tag::Invalid: {
            FML_DCHECK(false)
                << "Flutter PlatformView::OnScenicEvent: Got an invalid INPUT "
                   "event.";
          }
        }
        break;
      default: {
        break;
      }
    }
  }

  // If some View events went unmatched, try processing them again one more time
  // in case they arrived out-of-order with the View creation callback.
  if (!deferred_view_events.empty()) {
    task_runners_.GetPlatformTaskRunner()->PostTask(fml::MakeCopyable(
        [weak = weak_factory_.GetWeakPtr(),
         deferred_view_events = std::move(deferred_view_events)]() {
          if (!weak) {
            FML_LOG(WARNING)
                << "PlatformView already destroyed when "
                   "processing deferred view events; dropping events.";
            return;
          }

          for (const auto& event : deferred_view_events) {
            switch (event.Which()) {
              case fuchsia::ui::gfx::Event::Tag::kViewConnected: {
                bool view_found = weak->OnChildViewConnected(
                    event.view_connected().view_holder_id);
                FML_DCHECK(view_found);
                break;
              }
              case fuchsia::ui::gfx::Event::Tag::kViewDisconnected: {
                bool view_found = weak->OnChildViewDisconnected(
                    event.view_disconnected().view_holder_id);
                FML_DCHECK(view_found);
                break;
              }
              case fuchsia::ui::gfx::Event::Tag::kViewStateChanged: {
                bool view_found = weak->OnChildViewStateChanged(
                    event.view_state_changed().view_holder_id,
                    event.view_state_changed().state.is_rendering);
                FML_DCHECK(view_found);
                break;
              }
              default:
                FML_DCHECK(false) << "Flutter PlatformView::OnScenicEvent: Got "
                                     "an invalid deferred GFX event.";
                break;
            }
          }
        }));
  }

  // If any of the viewport metrics changed, inform the engine now.
  if (view_pixel_ratio_.has_value() && view_logical_size_.has_value() &&
      metrics_changed) {
    const float pixel_ratio = *view_pixel_ratio_;
    const std::array<float, 2> logical_size = *view_logical_size_;
    SetViewportMetrics({
        pixel_ratio,                    // device_pixel_ratio
        logical_size[0] * pixel_ratio,  // physical_width
        logical_size[1] * pixel_ratio,  // physical_height
        0.0f,                           // physical_padding_top
        0.0f,                           // physical_padding_right
        0.0f,                           // physical_padding_bottom
        0.0f,                           // physical_padding_left
        0.0f,                           // physical_view_inset_top
        0.0f,                           // physical_view_inset_right
        0.0f,                           // physical_view_inset_bottom
        0.0f,                           // physical_view_inset_left
        0.0f,                           // p_physical_system_gesture_inset_top
        0.0f,                           // p_physical_system_gesture_inset_right
        0.0f,  // p_physical_system_gesture_inset_bottom
        0.0f,  // p_physical_system_gesture_inset_left,
        -1.0,  // p_physical_touch_slop,
    });
  }
}

bool GfxPlatformView::OnChildViewConnected(scenic::ResourceId view_holder_id) {
  auto view_id_mapping = child_view_ids_.find(view_holder_id);
  if (view_id_mapping == child_view_ids_.end()) {
    return false;
  }

  std::ostringstream out;
  out << "{"
      << "\"method\":\"View.viewConnected\","
      << "\"args\":{"
      << "  \"viewId\":" << view_id_mapping->second  // ViewHolderToken handle
      << "  }"
      << "}";
  auto call = out.str();

  std::unique_ptr<flutter::PlatformMessage> message =
      std::make_unique<flutter::PlatformMessage>(
          "flutter/platform_views",
          fml::MallocMapping::Copy(call.c_str(), call.size()), nullptr);
  DispatchPlatformMessage(std::move(message));

  return true;
}

bool GfxPlatformView::OnChildViewDisconnected(
    scenic::ResourceId view_holder_id) {
  auto view_id_mapping = child_view_ids_.find(view_holder_id);
  if (view_id_mapping == child_view_ids_.end()) {
    return false;
  }

  std::ostringstream out;
  out << "{"
      << "\"method\":\"View.viewDisconnected\","
      << "\"args\":{"
      << "  \"viewId\":" << view_id_mapping->second  // ViewHolderToken handle
      << "  }"
      << "}";
  auto call = out.str();

  std::unique_ptr<flutter::PlatformMessage> message =
      std::make_unique<flutter::PlatformMessage>(
          "flutter/platform_views",
          fml::MallocMapping::Copy(call.c_str(), call.size()), nullptr);
  DispatchPlatformMessage(std::move(message));

  return true;
}

bool GfxPlatformView::OnChildViewStateChanged(scenic::ResourceId view_holder_id,
                                              bool is_rendering) {
  auto view_id_mapping = child_view_ids_.find(view_holder_id);
  if (view_id_mapping == child_view_ids_.end()) {
    return false;
  }

  const std::string is_rendering_str = is_rendering ? "true" : "false";
  std::ostringstream out;
  out << "{"
      << "\"method\":\"View.viewStateChanged\","
      << "\"args\":{"
      << "  \"viewId\":" << view_id_mapping->second << ","  // ViewHolderToken
      << "  \"is_rendering\":" << is_rendering_str << ","   // IsViewRendering
      << "  \"state\":" << is_rendering_str                 // IsViewRendering
      << "  }"
      << "}";
  auto call = out.str();

  std::unique_ptr<flutter::PlatformMessage> message =
      std::make_unique<flutter::PlatformMessage>(
          "flutter/platform_views",
          fml::MallocMapping::Copy(call.c_str(), call.size()), nullptr);
  DispatchPlatformMessage(std::move(message));

  return true;
}

void GfxPlatformView::OnCreateView(ViewCallback on_view_created,
                                   int64_t view_id_raw,
                                   bool hit_testable,
                                   bool focusable) {
  auto on_view_bound =
      [weak = weak_factory_.GetWeakPtr(),
       platform_task_runner = task_runners_.GetPlatformTaskRunner(),
       view_id = view_id_raw](scenic::ResourceId resource_id) {
        platform_task_runner->PostTask([weak, view_id, resource_id]() {
          if (!weak) {
            FML_LOG(WARNING)
                << "ViewHolder bound to PlatformView after PlatformView was "
                   "destroyed; ignoring.";
            return;
          }

          FML_DCHECK(weak->child_view_ids_.count(resource_id) == 0);
          weak->child_view_ids_[resource_id] = view_id;
        });
      };
  on_create_view_callback_(view_id_raw, std::move(on_view_created),
                           std::move(on_view_bound), hit_testable, focusable);
}

void GfxPlatformView::OnDisposeView(int64_t view_id_raw) {
  auto on_view_unbound =
      [weak = weak_factory_.GetWeakPtr(),
       platform_task_runner = task_runners_.GetPlatformTaskRunner()](
          scenic::ResourceId resource_id) {
        platform_task_runner->PostTask([weak, resource_id]() {
          if (!weak) {
            FML_LOG(WARNING)
                << "ViewHolder unbound from PlatformView after PlatformView"
                   "was destroyed; ignoring.";
            return;
          }

          FML_DCHECK(weak->child_view_ids_.count(resource_id) == 1);
          weak->child_view_ids_.erase(resource_id);
        });
      };
  on_destroy_view_callback_(view_id_raw, std::move(on_view_unbound));
}

}  // namespace flutter_runner
