// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Entrypoint for running a Flutter app on Fuchsia.
//
// Usage: ./main <path_to_flutter_asset_bundle>

#include <fuchsia/accessibility/semantics/cpp/fidl.h>
#include <fuchsia/fonts/cpp/fidl.h>
#include <fuchsia/scenic/scheduling/cpp/fidl.h>
#include <fuchsia/sysmem/cpp/fidl.h>
#include <fuchsia/ui/app/cpp/fidl.h>
#include <fuchsia/ui/composition/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async/default.h>
#include <lib/fdio/directory.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/fidl/cpp/interface_request.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/syslog/global.h>
#include <lib/ui/scenic/cpp/view_identity.h>
#include <lib/ui/scenic/cpp/view_ref_pair.h>
#include <zircon/status.h>

#include <string>

#include "platform_message_channels.h"
#include "src/embedder/accessibility_bridge.h"
#include "src/embedder/embedder_state.h"
#include "src/embedder/engine/embedder.h"
#include "src/embedder/flatland_ids.h"
#include "src/embedder/flatland_view_provider.h"
#include "src/embedder/fuchsia_logger.h"
#include "src/embedder/logging.h"
#include "src/embedder/mouse_delegate.h"
#include "src/embedder/platform_message_channels.h"
#include "src/embedder/root_inspect_node.h"
#include "src/embedder/software_surface.h"
#include "src/embedder/text_delegate.h"
#include "src/embedder/touch_delegate.h"

namespace embedder {
namespace {

// TODO(akbiggs): Don't hardcode this screen size, get it from
// an event instead.
constexpr int kScreenWidth = 1280;
constexpr int kScreenHeight = 800;

/// Gets the current name of the Fuchsia process that
/// is running the embedder.
std::string GetCurrentProcessName() {
  char name[ZX_MAX_NAME_LEN];
  zx_status_t status = zx::process::self()->get_property(ZX_PROP_NAME, name, sizeof(name));
  if (status != ZX_OK) {
    FX_LOG(ERROR, kLogTag, "Failed to get process name for sysmem; using \"\".");
    return std::string();
  }

  return std::string(name);
}

/// Gets the current process ID of the Fuchsia process that
/// is running the embedder.
zx_koid_t GetCurrentProcessId() {
  zx_info_handle_basic_t info;
  zx_status_t status =
      zx::process::self()->get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info),
                                    nullptr /* actual_count */, nullptr /* avail_count */);
  if (status != ZX_OK) {
    FX_LOG(ERROR, kLogTag, "Failed to get process ID for sysmem; using ZX_KOID_INVALID.");
    return ZX_KOID_INVALID;
  }

  return info.koid;
}

/// Return kernel object id for fuchsia view ref
zx_koid_t GetKoid(const fuchsia::ui::views::ViewRef& view_ref) {
  zx_handle_t handle = view_ref.reference.get();
  zx_info_handle_basic_t info;
  zx_status_t status =
      zx_object_get_info(handle, ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr);
  return status == ZX_OK ? info.koid : ZX_KOID_INVALID;
}

/// Handle platform message from dart application, forwarded from flutter engine
void FuchsiaHandlePlatformMessage(const FlutterPlatformMessage* message, void* user_data) {
  if (!strcmp(message->channel, kAccessibilityChannel)) {
    EmbedderState* embedder = static_cast<EmbedderState*>(user_data);
    embedder->accessibility_bridge_->HandlePlatformMessage(message);
  } else if (!strcmp(message->channel, kTextInputChannel)) {
    EmbedderState* embedder = static_cast<EmbedderState*>(user_data);
    embedder->text_delegate_->HandleFlutterTextInputChannelPlatformMessage(message);
  } else {
    FX_LOGF(INFO, embedder::kLogTag, "FuchsiaHandlePlatformMessage invoked: %s", message->channel);
  }
}

/// Fuchsia implementation of the Flutter Embedder update_semantics_callback
void FuchsiaHandleSemanticsUpdate(const FlutterSemanticsUpdate* update, void* user_data) {
  EmbedderState* embedder = static_cast<EmbedderState*>(user_data);
  embedder->accessibility_bridge_->AddSemanticsUpdate(update);
}

/// Fuchsia implementation of the Flutter Engine's |vsync_callback|.
void FuchsiaVsync(void* user_data, intptr_t baton) {
  EmbedderState* embedder = static_cast<EmbedderState*>(user_data);

  // Encourage the Engine to vsync for a 60Hz display.
  const uint64_t now_nanos = FlutterEngineGetCurrentTime();
  const uint64_t target_vsync_time = now_nanos + 16.6 * 1e6;
  FlutterEngineOnVsync(embedder->engine, baton, now_nanos, target_vsync_time);
}

/// Fuchsia implementation of the Flutter Engine's |log_message_callback|.
void FuchsiaLogMessage(const char* tag, const char* message, void* user_data) {
  FX_LOG(INFO, tag, message);
}

/// Callback for the embedder's FlutterEngineSendKeyEvent function.
void FuchsiaFlutterKeyEventCallback(bool handled, void* user_data) {
  FX_LOG(INFO, embedder::kLogTag, "FlutterKeyEventCallback invoked!");
}

void FuchsiaFlutterDataCallback(const uint8_t* data, size_t size, void* user_data) {
  auto message_data = static_cast<const unsigned char*>(data);
  FX_LOGF(INFO, embedder::kLogTag, "FuchsiaFlutterDataCallback invoked, data: %s", message_data);
}

/// Fuchsia implementation of the Flutter Engine's software rendering
/// |surface_acquire_callback|.
bool FuchsiaAcquireSoftwareSurface(void* user_data, size_t width, size_t height,
                                   uint8_t** allocation, size_t* stride) {
  EmbedderState* embedder = static_cast<EmbedderState*>(user_data);

  // TODO(akbiggs): Anything we need to do to clean up the old
  // software surface explicitly before reassigning here?
  embedder->software_surface = std::make_unique<SoftwareSurface>(
      embedder->sysmem_allocator, embedder->flatland_allocator,
      Size{.width = static_cast<uint32_t>(width), .height = static_cast<uint32_t>(height)});
  if (!embedder->software_surface->IsValid()) {
    FX_LOGF(ERROR, kLogTag, "Failed to acquire software surface of size (%lu, %lu).", width,
            height);
    return false;
  }

  // If we receive an unitialized surface, we need to create a
  // Flatland image and associate it with the surface.
  if (embedder->software_surface->GetImageId() == 0) {
    auto image_id = embedder->flatland_connection->NextContentId().value;
    const auto surface_size = embedder->software_surface->GetSize();

    fuchsia::math::SizeU image_size;
    image_size.width = surface_size.width;
    image_size.height = surface_size.height;

    fuchsia::ui::composition::ImageProperties image_properties;
    image_properties.set_size(image_size);

    embedder->flatland_connection->flatland()->CreateImage(
        {image_id}, embedder->software_surface->GetBufferCollectionImportToken(), 0,
        std::move(image_properties));

    embedder->software_surface->SetImageId(image_id);
    embedder->software_surface->SetReleaseImageCallback(
        [flatland = embedder->flatland_connection.get(), image_id]() {
          flatland->flatland()->ReleaseImage({image_id});
        });
  }

  // Enqueue fences for the next present.
  embedder->flatland_connection->EnqueueAcquireFence(embedder->software_surface->GetAcquireFence());
  embedder->flatland_connection->EnqueueReleaseFence(embedder->software_surface->GetReleaseFence());

  // Communicate the location of the allocated memory to Flutter so
  // Flutter can render into it.
  *allocation = embedder->software_surface->GetAllocation();
  *stride = embedder->software_surface->GetBytesPerRow();

  return true;
}

/// Fuchsia implementation of the Flutter Engine's software rendering
/// |surface_present_callback|.
bool FuchsiaPresentSoftwareSurface(void* user_data, const void* allocation, size_t row_bytes,
                                   size_t height) {
  EmbedderState* embedder = static_cast<EmbedderState*>(user_data);

  if (embedder->software_surface == nullptr) {
    // We have no surface acquired to present.
    return false;
  }

  // TODO(akbiggs): Replace with composition logic matching
  // https://github.com/flutter/engine/blob/main/shell/platform/fuchsia/flutter/flatland_external_view_embedder.cc#L108.
  auto image_id = embedder->software_surface->GetImageId();
  embedder->flatland_connection->flatland()->SetContent({kRootTransformId}, {image_id});
  embedder->flatland_connection->Present();

  // Signal to the rendered surface that we've finished writing.
  embedder->software_surface->SignalWritesFinished(
      /* on_read_finished = */ []() {
        // TODO(akbiggs): Anything we need to do after the read
        // finishes?
      });

  return true;
}

/// Runs the Flutter app whose assets (including snapshots) are located
/// at |assets_path| in the component's package.
///
/// The Engine instance will be stored in |embedder| and |embedder| will be
/// the user data for all callbacks from the Flutter Engine.
bool RunFlutterApp(const char* assets_path, EmbedderState* embedder) {
  FlutterRendererConfig renderer_config = {
      .type = kSoftware,
      .software =
          {
              .struct_size = sizeof(FlutterSoftwareRendererConfig),
              .surface_present_callback = FuchsiaPresentSoftwareSurface,
              .surface_acquire_callback = FuchsiaAcquireSoftwareSurface,
          },
  };
  // Connect and set up the system font provider.
  fuchsia::fonts::ProviderSyncPtr sync_font_provider;
  zx_status_t status = embedder->component_context->svc()->Connect<fuchsia::fonts::Provider>(
      sync_font_provider.NewRequest());
  if (status != ZX_OK) {
    FX_LOGF(ERROR, embedder::kLogTag, "Failed to connect to fonts provider service: %s",
            zx_status_get_string(status));
  }

  FlutterProjectArgs project_args = {
      .struct_size = sizeof(FlutterProjectArgs),
      .assets_path = assets_path,
      .platform_message_callback = FuchsiaHandlePlatformMessage,
      .vsync_callback = FuchsiaVsync,
      .log_message_callback = FuchsiaLogMessage,
      .log_tag = "flutter_app",
      .update_semantics_callback = FuchsiaHandleSemanticsUpdate,
      .font_initialization_data = sync_font_provider.Unbind().TakeChannel().release()};

  FlutterEngineResult result = FlutterEngineRun(FLUTTER_ENGINE_VERSION, &renderer_config,
                                                &project_args, embedder, &embedder->engine);

  if (result != kSuccess || embedder->engine == nullptr) {
    FX_LOGF(ERROR, kLogTag, "Could not run the Flutter Engine. Error code: %d",
            static_cast<int>(result));
    return false;
  }

  return true;
}

}  // namespace
}  // namespace embedder

int main(int argc, const char* argv[]) {
  if (argc != 2) {
    FX_LOG(ERROR, embedder::kLogTag, "usage: executable <path to flutter bundle>");
    return EXIT_FAILURE;
  }
  const char* assets_path = argv[1];

  embedder::EmbedderState embedder = {
      // This must be initialized before calling RunFlutterApp, as
      // this hack https://github.com/flutter/engine/pull/33472
      // relies
      // on it.
      .component_context = sys::ComponentContext::Create(),
  };

  // Serving the component context must happen after RunFlutterApp
  // because the embedder platform has a hack that adds inspect data
  // into the Dart VM using the component context
  // (https://github.com/flutter/engine/pull/33472).
  if (!embedder::RunFlutterApp(assets_path, &embedder)) {
    return EXIT_FAILURE;
  }

  // Ensure default dispatcher is set after caling RunFlutterApp
  FX_CHECK(async_get_default_dispatcher());

  // Necessary to get Flutter to render frames.
  FlutterWindowMetricsEvent window_metrics_event = {
      .struct_size = sizeof(FlutterWindowMetricsEvent),

      // TODO(akbiggs): Don't hardcode these.
      .width = embedder::kScreenWidth,
      .height = embedder::kScreenHeight,

      .pixel_ratio = 1,
      .left = 0,
      .top = 0,
      .physical_view_inset_top = 0,
      .physical_view_inset_right = 0,
      .physical_view_inset_bottom = 0,
      .physical_view_inset_left = 0,
  };
  FlutterEngineSendWindowMetricsEvent(embedder.engine, &window_metrics_event);

  // Connect to Keyboard service.
  fuchsia::ui::input3::KeyboardHandle keyboard;
  zx_status_t keyboard_status =
      embedder.component_context->svc()->Connect<fuchsia::ui::input3::Keyboard>(
          keyboard.NewRequest());
  if (keyboard_status != ZX_OK) {
    FX_LOGF(ERROR, embedder::kLogTag, "Failed to connect to fuchsia::ui::input3::Keyboard: %s",
            zx_status_get_string(keyboard_status));
    return EXIT_FAILURE;
  }

  // Connect to ImeService service.
  fuchsia::ui::input::ImeServiceHandle ime_service;
  zx_status_t ime_status =
      embedder.component_context->svc()->Connect<fuchsia::ui::input::ImeService>(
          ime_service.NewRequest());
  if (ime_status != ZX_OK) {
    FX_LOGF(ERROR, embedder::kLogTag, "Failed to connect to fuchsia::ui::input::ImeService: %s",
            zx_status_get_string(ime_status));
  }

  // Connect to Flatland.
  fuchsia::ui::composition::FlatlandHandle flatland_handle;
  zx_status_t status =
      embedder.component_context->svc()->Connect<fuchsia::ui::composition::Flatland>(
          flatland_handle.NewRequest());
  if (status != ZX_OK) {
    FX_LOGF(ERROR, embedder::kLogTag, "Failed to connect to Flatland: %s",
            zx_status_get_string(status));
    return EXIT_FAILURE;
  }
  // TODO(akbiggs): Create this on the raster thread per
  // FlatlandConnection's documentation.
  embedder.flatland_connection = std::make_unique<embedder::FlatlandConnection>(
      // TODO(akbiggs): Pick a more appropriate debug name based
      // on the Flutter app name.
      "FlutterEmbedder" /* debug_name */, std::move(flatland_handle),
      /* on_error_callback = */
      []() {
        // TODO(akbiggs): What should we do on errors?
      },
      /* on_frame_presented_callback = */
      [](fuchsia::scenic::scheduling::FramePresentedInfo info) {
        // TODO(akbiggs): What should we do after a frame
        // finishes presenting?
      });

  // Focuser for programatically transfering View focus.
  fuchsia::ui::views::FocuserHandle focuser;
  fuchsia::ui::views::ViewRefFocusedHandle view_ref_focused;

  // The protocol endpoints bound to a Flatland ViewCreationToken.
  fuchsia::ui::composition::ViewBoundProtocols flatland_view_protocols;
  flatland_view_protocols.set_view_focuser(focuser.NewRequest());
  flatland_view_protocols.set_view_ref_focused(view_ref_focused.NewRequest());

  // Mouse & Touch source
  fuchsia::ui::pointer::MouseSourceHandle mouse_source;
  fuchsia::ui::pointer::TouchSourceHandle touch_source;
  flatland_view_protocols.set_touch_source(touch_source.NewRequest());
  flatland_view_protocols.set_mouse_source(mouse_source.NewRequest());

  auto view_ref_pair = scenic::ViewRefPair::New();

  fuchsia::ui::views::ViewRef platform_view_ref;
  view_ref_pair.view_ref.Clone(&platform_view_ref);
  fuchsia::ui::views::ViewRef accessibility_view_ref;
  view_ref_pair.view_ref.Clone(&accessibility_view_ref);

  // Response handle attached to a FlutterPlatformMessage to be called in the engine.
  FlutterPlatformMessageResponseHandle* response_handle;
  FlutterPlatformMessageCreateResponseHandle(embedder.engine, embedder::FuchsiaFlutterDataCallback,
                                             &embedder, &response_handle);

  // Keyboard/Text input.
  embedder.text_delegate_ = std::make_unique<embedder::TextDelegate>(
      std::move(platform_view_ref), std::move(ime_service), std::move(keyboard),
      /* key_event_dispatch_callback: [flutter/keydata] */
      [&embedder](const FlutterKeyEvent* event) {
        // Send key event to the engine.
        FlutterEngineResult result = FlutterEngineSendKeyEvent(
            embedder.engine, event, embedder::FuchsiaFlutterKeyEventCallback, &embedder);

        if (result != kSuccess) {
          FX_LOGF(INFO, embedder::kLogTag, "FlutterEngineSendKeyEvent failed for the %s channel.",
                  embedder::kKeyDataChannel);
        }
      },
      /*platform_dispatch_callback: [flutter/keyevent, flutter/textinput] */
      [&embedder](const FlutterPlatformMessage* message) {
        // Send platform message to the engine.
        FlutterEngineResult result = FlutterEngineSendPlatformMessage(embedder.engine, message);

        if (result != kSuccess) {
          FX_LOGF(INFO, embedder::kLogTag,
                  "FlutterEngineSendPlatformMessage failed for the %s channel.", message->channel);
        }
      },
      response_handle);

  embedder::FlatlandViewProvider view_provider(embedder.flatland_connection.get(),
                                               std::move(view_ref_pair),
                                               std::move(flatland_view_protocols));

  auto send_pointer_events_to_engine = [&embedder](std::vector<FlutterPointerEvent> events) {
    if (events.empty())
      return;
    FlutterEngineSendPointerEvent(embedder.engine, &events[0], events.size());
  };

  auto mouse_delegate = std::make_unique<embedder::MouseDelegate>(std::move(mouse_source));
  auto touch_delegate = std::make_unique<embedder::TouchDelegate>(std::move(touch_source));
  mouse_delegate->WatchLoop(send_pointer_events_to_engine);
  touch_delegate->WatchLoop(send_pointer_events_to_engine);

  // Return to ViewProvider Initialization
  fidl::BindingSet<fuchsia::ui::app::ViewProvider> view_provider_bindings;
  status = embedder.component_context->outgoing()->AddPublicService<fuchsia::ui::app::ViewProvider>(
      [&view_provider,
       &view_provider_bindings](fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider> request) {
        view_provider_bindings.AddBinding(&view_provider, std::move(request));
      });
  if (status != ZX_OK) {
    FX_LOGF(ERROR, embedder::kLogTag, "Failed to add ViewProvider service: %s",
            zx_status_get_string(status));
    return EXIT_FAILURE;
  }

  // Our run loop's dispatcher must be used to serve the component
  // context in order for requests' handlers to get called while
  // we're looping.
  status = embedder.component_context->outgoing()->ServeFromStartupInfo();
  if (status != ZX_OK) {
    FX_LOGF(ERROR, embedder::kLogTag, "Failed to serve component context: %s",
            zx_status_get_string(status));
    return EXIT_FAILURE;
  }

  // Set up sysmem allocator for software rendering.
  status = fdio_service_connect("/svc/fuchsia.sysmem.Allocator",
                                embedder.sysmem_allocator.NewRequest().TakeChannel().release());
  embedder.sysmem_allocator->SetDebugClientInfo(embedder::GetCurrentProcessName(),
                                                embedder::GetCurrentProcessId());
  if (status != ZX_OK) {
    FX_LOGF(ERROR, embedder::kLogTag, "Failed to connect to fuchsia.sysmem.Allocator: %s",
            zx_status_get_string(status));
    return EXIT_FAILURE;
  }

  // Set up Flatland allocator for software rendering.
  status = fdio_service_connect("/svc/fuchsia.ui.composition.Allocator",
                                embedder.flatland_allocator.NewRequest().TakeChannel().release());
  if (status != ZX_OK) {
    FX_LOGF(ERROR, embedder::kLogTag, "Failed to connect to fuchsia.ui.composition.Allocator: %s",
            zx_status_get_string(status));
    return EXIT_FAILURE;
  }

  embedder::AccessibilityBridge::SetSemanticsEnabledCallback set_semantics_enabled_callback =
      [&embedder](bool enabled) { FlutterEngineUpdateSemanticsEnabled(embedder.engine, enabled); };

  embedder::AccessibilityBridge::DispatchSemanticsActionCallback
      dispatch_semantics_action_callback =
          [&embedder](int32_t node_id, FlutterSemanticsAction action) {
            FlutterEngineDispatchSemanticsAction(embedder.engine, node_id, action, nullptr, 0);
          };

  const std::string accessibility_inspect_name =
      std::to_string(embedder::GetKoid(accessibility_view_ref));

  // Connect to SemanticsManager service.
  fuchsia::accessibility::semantics::SemanticsManagerHandle semantics_manager;

  status = embedder.component_context->svc()
               ->Connect<fuchsia::accessibility::semantics::SemanticsManager>(
                   semantics_manager.NewRequest());

  if (status != ZX_OK) {
    FX_LOGF(ERROR, embedder::kLogTag,
            "fuchsia::accessibility::semantics::SemanticsManager connection failed: %s",
            zx_status_get_string(status));
  }

  dart_utils::RootInspectNode::Initialize(embedder.component_context.get());

  embedder.accessibility_bridge_ = std::make_unique<embedder::AccessibilityBridge>(
      std::move(set_semantics_enabled_callback), std::move(dispatch_semantics_action_callback),
      std::move(semantics_manager), std::move(accessibility_view_ref),
      dart_utils::RootInspectNode::CreateRootChild(std::move(accessibility_inspect_name)));

  view_provider.SetPixelRatioCallback(
      [&embedder](float ratio) { embedder.accessibility_bridge_->SetPixelRatio(ratio); });

  // TODO(benbergkamp): temporary a workaround
  FlutterEngineRunMessageLoop();

  FX_LOG(INFO, embedder::kLogTag, "Done looping.");
  return EXIT_SUCCESS;
}
