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

#include "vc-display.h"

#include <fcntl.h>
#include <fuchsia/hardware/display/controller/c/banjo.h>
#include <fuchsia/hardware/display/llcpp/fidl.h>
#include <fuchsia/io/llcpp/fidl.h>
#include <fuchsia/sysmem/llcpp/fidl.h>
#include <lib/async/cpp/wait.h>
#include <lib/fdio/cpp/caller.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/io.h>
#include <lib/fidl/coding.h>
#include <lib/fidl/llcpp/connect_service.h>
#include <lib/image-format-llcpp/image-format-llcpp.h>
#include <lib/service/llcpp/service.h>
#include <lib/statusor/endpoint-or-error.h>
#include <lib/statusor/status-macros.h>
#include <lib/zx/channel.h>
#include <lib/zx/vmo.h>
#include <string.h>
#include <zircon/assert.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>

#include <fbl/unique_fd.h>
#include <src/lib/fsl/handles/object_info.h>

#include "vc.h"

namespace fhd = fuchsia_hardware_display;
namespace sysmem = fuchsia_sysmem;
namespace fio = fuchsia_io;

using fhd::wire::VirtconMode;

static async_dispatcher_t* dc_dispatcher = nullptr;
// At any point, |dc_wait| will either be waiting on the display controller device directory
// for a display controller instance or it will be waiting on a display controller interface
// for messages.
static async::Wait dc_wait;

static std::unique_ptr<fidl::WireSyncClient<fhd::Controller>> dc_client;

static std::unique_ptr<fidl::WireSyncClient<sysmem::Allocator>> sysmem_allocator;
static uint64_t next_buffer_collection_id = 1;

static struct list_node display_list = LIST_INITIAL_VALUE(display_list);
static bool primary_bound = false;
static bool g_hide_on_boot = false;

// remember whether the virtual console controls the display
bool g_vc_owns_display = false;

static void vc_find_display_controller();

bool is_primary_bound() { return primary_bound; }

#if BUILD_FOR_DISPLAY_TEST

struct list_node* get_display_list() {
  return &display_list;
}

fidl::WireSyncClient<sysmem::Allocator>* get_sysmem_allocator() { return sysmem_allocator.get(); }

#endif  // BUILD_FOR_DISPLAY_TEST

static constexpr const char* kDisplayControllerDir = "/dev/class/display-controller";
static int dc_dir_fd;
static zx_handle_t dc_device;

static zx_status_t vc_set_mode(VirtconMode mode) {
  return dc_client->SetVirtconMode(static_cast<uint8_t>(mode)).status();
}

void vc_attach_to_main_display(vc_t* vc) {
  if (list_is_empty(&display_list)) {
    return;
  }
  display_info_t* primary = list_peek_head_type(&display_list, display_info_t, node);
  vc->graphics = primary->graphics;
  vc_attach_gfx(vc);
}

void vc_toggle_framebuffer() {
  if (list_is_empty(&display_list)) {
    return;
  }

  zx_status_t status =
      vc_set_mode(!g_vc_owns_display ? VirtconMode::FORCED : VirtconMode::FALLBACK);
  if (status != ZX_OK) {
    printf("vc: Failed to toggle ownership %d\n", status);
  }
}

static void handle_ownership_change(bool has_ownership) {
  g_vc_owns_display = has_ownership;

#if !BUILD_FOR_DISPLAY_TEST
  // If we've gained it, repaint
  if (g_vc_owns_display && g_active_vc) {
    vc_full_repaint(g_active_vc);
    vc_render(g_active_vc);
  }
#endif  // !BUILD_FOR_DISPLAY_TEST
}

zx_status_t create_layer(uint64_t display_id, uint64_t* layer_id) {
  auto rsp = dc_client->CreateLayer();
  RETURN_IF_ERROR(rsp, "vc: Create layer call failed");

  if (rsp->res != ZX_OK) {
    printf("vc: Failed to create layer %d\n", rsp->res);
    return rsp->res;
  }

  *layer_id = rsp->layer_id;
  return ZX_OK;
}

void destroy_layer(uint64_t layer_id) {
  if (!dc_client->DestroyLayer(layer_id).ok()) {
    printf("vc: Failed to destroy layer\n");
  }
}

void release_image(uint64_t image_id) {
  if (!dc_client->ReleaseImage(image_id).ok()) {
    printf("vc: Failed to release image\n");
  }
}

static zx_status_t handle_display_added(fhd::wire::Info* info) {
  display_info_t* display_info =
      reinterpret_cast<display_info_t*>(calloc(1, sizeof(display_info_t)));
  if (!display_info) {
    printf("vc: failed to alloc display info\n");
    return ZX_ERR_NO_MEMORY;
  }

  zx_status_t status;
  if ((status = create_layer(info->id, &display_info->layer_id)) != ZX_OK) {
    printf("vc: failed to create display layer\n");
    free(display_info);
    return status;
  }

  display_info->id = info->id;
  display_info->width = info->modes[0].horizontal_resolution;
  display_info->height = info->modes[0].vertical_resolution;
  display_info->format = static_cast<int32_t>(info->pixel_format[0]);
  display_info->image_id = 0;
  display_info->image_vmo = ZX_HANDLE_INVALID;
  display_info->buffer_collection_id = 0;
  display_info->bound = false;
  display_info->log_vc = nullptr;
  display_info->graphics = nullptr;

  list_add_tail(&display_list, &display_info->node);

  return ZX_OK;
}

void handle_display_removed(uint64_t id) {
  if (list_is_empty(&display_list)) {
    printf("vc: No displays when removing %ld\n", id);
    return;
  }

  bool was_primary = list_peek_head_type(&display_list, display_info_t, node)->id == id;
  display_info_t* info = nullptr;
  display_info_t* temp = nullptr;
  list_for_every_entry_safe (&display_list, info, temp, display_info_t, node) {
    if (info->id == id) {
      destroy_layer(info->layer_id);
      release_image(info->image_id);
      list_delete(&info->node);
      zx_handle_close(info->image_vmo);
      if (info->buffer_collection_id) {
        dc_client->ReleaseBufferCollection(info->buffer_collection_id);
      }

      if (info->graphics) {
        free(info->graphics);
      }
      if (info->log_vc) {
        log_delete_vc(info->log_vc);
      }
      free(info);
    }
  }

  if (was_primary) {
    set_log_listener_active(false);
    primary_bound = false;
  }
}

static zx_status_t get_single_framebuffer(zx_handle_t* vmo_out, uint32_t* stride_out) {
  auto rsp = dc_client->GetSingleBufferFramebuffer();
  RETURN_IF_ERROR(rsp, "vc: Failed to get single framebuffer");
  if (rsp->res != ZX_OK) {
    // Don't print an error since this can happen on non-single-framebuffer
    // systems.
    return rsp->res;
  }
  if (!rsp->vmo) {
    return ZX_ERR_INTERNAL;
  }

  *vmo_out = rsp->vmo.release();
  *stride_out = rsp->stride;
  return ZX_OK;
}

zx_status_t import_buffer_collection(uint64_t collection_id, fhd::wire::ImageConfig* config,
                                     uint64_t* id) {
  constexpr uint32_t kImageIndex = 0;
  auto import_rsp = dc_client->ImportImage(*config, collection_id, kImageIndex);
  RETURN_IF_ERROR(import_rsp, "vc: Failed to import image call");

  if (import_rsp->res != ZX_OK) {
    printf("vc: Failed to import vmo collection %d\n", import_rsp->res);
    return import_rsp->res;
  }

  *id = import_rsp->image_id;
  return ZX_OK;
}

zx_status_t import_vmo(zx_handle_t vmo, fhd::wire::ImageConfig* config, uint64_t* id) {
  zx_handle_t vmo_dup;
  zx_status_t status;
  if ((status = zx_handle_duplicate(vmo, ZX_RIGHT_SAME_RIGHTS, &vmo_dup)) != ZX_OK) {
    printf("vc: Failed to dup fb handle %d\n", status);
    return status;
  }

  auto import_rsp = dc_client->ImportVmoImage(*config, zx::vmo(vmo_dup), 0);
  RETURN_IF_ERROR(import_rsp, "vc: Failed to import vmo call");

  if (import_rsp->res != ZX_OK) {
    printf("vc: Failed to import vmo %d\n", import_rsp->res);
    return import_rsp->res;
  }

  *id = import_rsp->image_id;
  return ZX_OK;
}

zx_status_t set_display_layer(uint64_t display_id, uint64_t layer_id) {
  RETURN_IF_ERROR(dc_client->SetDisplayLayers(display_id, fidl::VectorView<uint64_t>::FromExternal(
                                                              &layer_id, layer_id ? 1 : 0)),
                  "vc: Failed to set display layers");
  return ZX_OK;
}

zx_status_t configure_layer(display_info_t* display, uint64_t layer_id, uint64_t image_id,
                            fhd::wire::ImageConfig* config) {
  RETURN_IF_ERROR(dc_client->SetLayerPrimaryConfig(layer_id, *config),
                  "vc: Failed to set layer config");
  RETURN_IF_ERROR(dc_client->SetLayerPrimaryPosition(
                      layer_id, fhd::wire::Transform::IDENTITY,
                      fhd::wire::Frame{.width = config->width, .height = config->height},
                      fhd::wire::Frame{.width = display->width, .height = display->height}),
                  "vc: Failed to set layer position");
  RETURN_IF_ERROR(dc_client->SetLayerImage(layer_id, image_id, 0, 0), "vc: Failed to set image");
  return ZX_OK;
}

zx_status_t apply_configuration() {
  // Validate and then apply the new configuration
  auto check_rsp = dc_client->CheckConfig(false);
  RETURN_IF_ERROR(check_rsp, "vc: Failed to validate display config");

  if (check_rsp->res != fhd::wire::ConfigResult::OK) {
    printf("vc: Config not valid %d\n", static_cast<int>(check_rsp->res));
    return ZX_ERR_INTERNAL;
  }

  RETURN_IF_ERROR(dc_client->ApplyConfig(), "Applying config failed");

  return ZX_OK;
}

static zx_status_t create_buffer_collection(
    display_info_t* display, uint64_t id,
    std::unique_ptr<fidl::WireSyncClient<sysmem::BufferCollection>>* collection_client) {
  fidl::ClientEnd<sysmem::BufferCollectionToken> token;
  {
    zx::status token_server = fidl::CreateEndpoints(&token);
    if (token_server.is_error()) {
      printf("vc: Failed to create collection channel: %d\n", token_server.status_value());
      return token_server.status_value();
    }
    zx_status_t status =
        sysmem_allocator->AllocateSharedCollection(std::move(*token_server)).status();
    if (status != ZX_OK) {
      printf("vc: Failed to allocate shared collection: %d\n", status);
      return status;
    }
  }
  constexpr uint32_t kVcNamePriority = 1000000;
  const char kVcCollectionName[] = "vc-framebuffer";
  zx_status_t status =
      fidl::WireCall(token).SetName(kVcNamePriority, fidl::StringView(kVcCollectionName)).status();
  if (status != ZX_OK) {
    printf("vc: Failed to set debug info: %d\n", status);
    return status;
  }

  fidl::ClientEnd<sysmem::BufferCollectionToken> display_token;
  {
    zx::status display_token_server = fidl::CreateEndpoints(&display_token);
    if (display_token_server.is_error()) {
      printf("vc: Failed to allocate display token: %d\n", display_token_server.status_value());
      return display_token_server.status_value();
    }

    status = fidl::WireCall(token)
                 .Duplicate(ZX_RIGHT_SAME_RIGHTS, *std::move(display_token_server))
                 .status();
    if (status != ZX_OK) {
      printf("vc: Failed to duplicate token: %d\n", status);
      return status;
    }
  }

  fidl::WireSyncClient<sysmem::BufferCollection> collection;
  {
    auto endpoints = fidl::CreateEndpoints<sysmem::BufferCollection>();
    if (endpoints.is_error()) {
      printf("vc: Failed to create collection channel: %d\n", endpoints.status_value());
      return endpoints.status_value();
    }
    status = sysmem_allocator->BindSharedCollection(std::move(token), std::move(endpoints->server))
                 .status();
    if (status != ZX_OK) {
      printf("vc: Failed to bind collection: %d\n", status);
      return status;
    }
    collection = fidl::BindSyncClient(std::move(endpoints->client));
  }
  status = collection.Sync().status();
  if (status != ZX_OK) {
    printf("vc: Failed to sync collection: %d\n", status);
    return status;
  }

  auto import_rsp = dc_client->ImportBufferCollection(id, std::move(display_token));
  RETURN_IF_ERROR(import_rsp, "vc: Failed to import buffer collection");
  if (import_rsp->res != ZX_OK) {
    printf("vc: Import buffer collection error\n");
    return import_rsp->res;
  }

  auto set_display_constraints =
      dc_client->SetBufferCollectionConstraints(id, display->image_config);
  RETURN_IF_ERROR(set_display_constraints, "vc: Failed to set display constraints");
  if (set_display_constraints->res != ZX_OK) {
    printf("vc: Display constraints error\n");
    return set_display_constraints->res;
  }

  sysmem::wire::BufferCollectionConstraints constraints;
  constraints.usage.cpu = sysmem::wire::cpuUsageWriteOften | sysmem::wire::cpuUsageRead;
  constraints.min_buffer_count = 1;
  constraints.has_buffer_memory_constraints = true;
  constraints.buffer_memory_constraints = image_format::GetDefaultBufferMemoryConstraints();
  constraints.buffer_memory_constraints.ram_domain_supported = true;

  constraints.image_format_constraints_count = 1;
  auto& image_constraints = constraints.image_format_constraints[0];
  image_constraints = image_format::GetDefaultImageFormatConstraints();
  fuchsia_sysmem_PixelFormat pixel_format;
  if (!ImageFormatConvertZxToSysmem(display->format, &pixel_format)) {
    printf("vc: Unsupported pixel format\n");
    return ZX_ERR_INVALID_ARGS;
  }
  image_constraints.pixel_format = image_format::GetCppPixelFormat(pixel_format);
  image_constraints.color_spaces_count = 1;
  image_constraints.color_space[0].type = sysmem::wire::ColorSpaceType::SRGB;
  image_constraints.min_coded_width = display->width;
  image_constraints.min_coded_height = display->height;
  image_constraints.max_coded_width = 0xffffffff;
  image_constraints.max_coded_height = 0xffffffff;
  image_constraints.min_bytes_per_row = 0;
  image_constraints.max_bytes_per_row = 0xffffffff;

  RETURN_IF_ERROR(collection.SetConstraints(true, constraints), "vc: Failed to set constraints");
  *collection_client =
      std::make_unique<fidl::WireSyncClient<sysmem::BufferCollection>>(std::move(collection));
  return ZX_OK;
}

zx_status_t alloc_display_info_vmo(display_info_t* display) {
  display->buffer_collection_id = 0;
  display->image_config.height = display->height;
  display->image_config.width = display->width;
  display->image_config.pixel_format = display->format;
  display->image_config.type = IMAGE_TYPE_SIMPLE;
  if (get_single_framebuffer(&display->image_vmo, &display->stride) != ZX_OK) {
    uint64_t buffer_collection_id = next_buffer_collection_id++;
    std::unique_ptr<fidl::WireSyncClient<sysmem::BufferCollection>> collection_client;
    zx_status_t status =
        create_buffer_collection(display, buffer_collection_id, &collection_client);
    if (status != ZX_OK) {
      return status;
    }
    display->buffer_collection_id = buffer_collection_id;

    auto info_result = collection_client->WaitForBuffersAllocated();
    RETURN_IF_ERROR(info_result, "vc: Couldn't wait for buffers allocated");
    if (info_result->status != ZX_OK) {
      printf("vc: Couldn't wait for buffers allocated\n");
      return info_result->status;
    }

    uint32_t bytes_per_row;
    bool got_stride = image_format::GetMinimumRowBytes(
        info_result->buffer_collection_info.settings.image_format_constraints, display->width,
        &bytes_per_row);

    if (!got_stride) {
      return ZX_ERR_INVALID_ARGS;
    }
    display->stride = bytes_per_row / ZX_PIXEL_FORMAT_BYTES(display->format);
    display->image_vmo = info_result->buffer_collection_info.buffers[0].vmo.release();
    collection_client->Close();
  }
  return ZX_OK;
}

zx_status_t rebind_display(bool use_all) {
  // Arbitrarily pick the oldest display as the primary dispay
  display_info* primary = list_peek_head_type(&display_list, display_info, node);
  if (primary == nullptr) {
    printf("vc: No display to bind to\n");
    return ZX_ERR_NO_RESOURCES;
  }

  zx_status_t status;
  // This happens when the last primary disconnected and a new, already
  // bound display becomes primary. We must un-bind the display and
  // rebind.
  if (!primary_bound && primary->bound) {
    // Remove the primary display's log console.
    if (primary->log_vc) {
      log_delete_vc(primary->log_vc);
      primary->log_vc = nullptr;
    }
    // Switch all of the current vcs to using this display.
    vc_change_graphics(primary->graphics);
  }

  display_info_t* info = nullptr;
  list_for_every_entry (&display_list, info, display_info_t, node) {
    if (!use_all && info != primary) {
      // If we're not showing anything on this display, remove its layer.
      if ((status = set_display_layer(info->id, 0)) != ZX_OK) {
        break;
      }
    } else if (info->image_id == 0) {
      // If we want to display something but aren't, configure the display.
      if ((status = alloc_display_info_vmo(info)) != ZX_OK) {
        printf("vc: failed to allocate vmo for new display %d\n", status);
        break;
      }

      info->graphics = reinterpret_cast<vc_gfx_t*>(calloc(1, sizeof(vc_gfx_t)));
      if ((status = vc_init_gfx(info->graphics, info->image_vmo, info->width, info->height,
                                info->format, info->stride)) != ZX_OK) {
        printf("vc: failed to initialize graphics for new display %d\n", status);
        break;
      }

      // If this is not the primary display then create the log console
      // for the display.
      if (info != primary) {
        if ((status = log_create_vc(info->graphics, &info->log_vc)) != ZX_OK) {
          break;
        }
      }
      info->bound = true;

      fhd::wire::ImageConfig config = info->image_config;
      if (info->buffer_collection_id) {
        if ((status = import_buffer_collection(info->buffer_collection_id, &config,
                                               &info->image_id)) != ZX_OK) {
          break;
        }
      } else {
        if ((status = import_vmo(info->image_vmo, &config, &info->image_id)) != ZX_OK) {
          break;
        }
      }

      if ((status = set_display_layer(info->id, info->layer_id)) != ZX_OK) {
        break;
      }

      if ((status = configure_layer(info, info->layer_id, info->image_id, &config) != ZX_OK)) {
        break;
      }
    }
  }

  if (status == ZX_OK && apply_configuration() == ZX_OK) {
    // Only listen for logs when we have somewhere to print them. Also,
    // use a repeating wait so that we don't add/remove observers for each
    // log message (which is helpful when tracing the addition/removal of
    // observers).
    set_log_listener_active(true);
    vc_change_graphics(primary->graphics);

    printf("vc: Successfully attached to display %ld\n", primary->id);
    primary_bound = true;
    return ZX_OK;
  } else {
    display_info_t* info = nullptr;
    list_for_every_entry (&display_list, info, display_info_t, node) {
      if (info->image_id) {
        release_image(info->image_id);
        info->image_id = 0;
      }
      if (info->image_vmo) {
        zx_handle_close(info->image_vmo);
        info->image_vmo = 0;
      }
      if (info->graphics) {
        free(info->graphics);
        info->graphics = nullptr;
      }
    }

    if (use_all) {
      return rebind_display(false);
    } else {
      printf("vc: Failed to bind to displays\n");
      return ZX_ERR_INTERNAL;
    }
  }
}

static zx_status_t handle_displays_changed(fidl::VectorView<fhd::wire::Info>& added,
                                           fidl::VectorView<uint64_t>& removed) {
  for (auto& display : added) {
    zx_status_t status = handle_display_added(&display);
    if (status != ZX_OK) {
      return status;
    }
  }

  for (auto& display_id : removed) {
    handle_display_removed(display_id);
  }

  return rebind_display(true);
}

zx_status_t dc_callback_handler(zx_signals_t signals) {
  if (signals & ZX_CHANNEL_PEER_CLOSED) {
    printf("vc: Displays lost\n");
    while (!list_is_empty(&display_list)) {
      handle_display_removed(list_peek_head_type(&display_list, display_info_t, node)->id);
    }
    vc_change_graphics(nullptr);

    zx_handle_close(dc_device);
    dc_client.reset();

    vc_find_display_controller();

    return ZX_ERR_STOP;
  }

  ZX_DEBUG_ASSERT(signals & ZX_CHANNEL_READABLE);

  class EventHandler : public fidl::WireSyncEventHandler<fhd::Controller> {
   public:
    EventHandler() = default;

    void OnDisplaysChanged(fidl::WireResponse<fhd::Controller::OnDisplaysChanged>* event) override {
      handle_displays_changed(event->added, event->removed);
    }

    void OnVsync(fidl::WireResponse<fhd::Controller::OnVsync>* event) override {}

    void OnClientOwnershipChange(
        fidl::WireResponse<fhd::Controller::OnClientOwnershipChange>* event) override {
      handle_ownership_change(event->has_ownership);
    }

    zx_status_t Unknown() override {
      printf("vc: Unknown display callback message\n");
      return ZX_OK;
    }
  };

  EventHandler event_handler;
  return dc_client->HandleOneEvent(event_handler).status();
}

#if BUILD_FOR_DISPLAY_TEST
void initialize_display_channel(fidl::ClientEnd<fhd::Controller> channel) {
  dc_client = std::make_unique<fidl::WireSyncClient<fhd::Controller>>(
      fidl::BindSyncClient(std::move(channel)));

  dc_wait.set_object(dc_client->channel().get());
}

#else

static zx_status_t vc_dc_event(uint32_t evt, const char* name) {
  if ((evt != fio::wire::WATCH_EVENT_EXISTING) && (evt != fio::wire::WATCH_EVENT_ADDED)) {
    return ZX_OK;
  }

  printf("vc: new display device %s/%s\n", kDisplayControllerDir, name);

  char buf[64];
  snprintf(buf, 64, "%s/%s", kDisplayControllerDir, name);
  fbl::unique_fd fd(open(buf, O_RDWR));
  if (!fd) {
    printf("vc: failed to open display controller device\n");
    return ZX_OK;
  }

  zx::channel device_server, device_client;
  zx_status_t status = zx::channel::create(0, &device_server, &device_client);
  if (status != ZX_OK) {
    return status;
  }

  auto dc_endpoints = fidl::CreateEndpoints<fhd::Controller>();
  if (dc_endpoints.is_error()) {
    return dc_endpoints.status_value();
  }

  fdio_cpp::FdioCaller caller(std::move(fd));
  auto open_rsp =
      fidl::WireCall(caller.borrow_as<fhd::Provider>())
          .OpenVirtconController(std::move(device_server), std::move(dc_endpoints->server));
  if (!open_rsp.ok()) {
    return open_rsp.status();
  }
  if (open_rsp->s != ZX_OK) {
    return open_rsp->s;
  }

  dc_device = device_client.release();
  dc_client =
      std::make_unique<fidl::WireSyncClient<fhd::Controller>>(std::move(dc_endpoints->client));

  zx_handle_close(dc_wait.object());

  status = vc_set_mode(g_hide_on_boot ? fhd::wire::VirtconMode::INACTIVE
                                      : fhd::wire::VirtconMode::FALLBACK);
  if (status != ZX_OK) {
    printf("vc: Failed to set initial ownership %d\n", status);
    vc_find_display_controller();
    return ZX_ERR_STOP;
  }

  ZX_DEBUG_ASSERT(!dc_wait.is_pending());
  dc_wait.set_object(dc_client->channel().get());
  dc_wait.set_trigger(ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED);
  dc_wait.set_handler([](async_dispatcher_t* dispatcher, async::Wait* wait, zx_status_t status,
                         const zx_packet_signal_t* signal) {
    if (status != ZX_OK) {
      return;
    }
    status = dc_callback_handler(signal->observed);
    if (status != ZX_OK) {
      return;
    }
    wait->Begin(dispatcher);
  });

  status = dc_wait.Begin(dc_dispatcher);
  if (status != ZX_OK) {
    printf("vc: Failed to set port waiter %d\n", status);
    vc_find_display_controller();
  }
  return ZX_ERR_STOP;
}

#endif  // BUILD_FOR_DISPLAY_TEST

zx_status_t handle_device_dir_event(zx_handle_t handle, zx_signals_t signals,
                                    zx_status_t (*event_handler)(unsigned event, const char* msg)) {
  if (!(signals & ZX_CHANNEL_READABLE)) {
    printf("vc: device directory died\n");
    return ZX_ERR_STOP;
  }

  // Buffer contains events { Opcode, Len, Name[Len] }
  // See zircon/device/vfs.h for more detail
  // extra byte is for temporary NUL
  uint8_t buf[fio::wire::MAX_BUF + 1];
  uint32_t len;
  if (zx_channel_read(handle, 0, buf, nullptr, sizeof(buf) - 1, 0, &len, nullptr) < 0) {
    printf("vc: failed to read from device directory\n");
    return ZX_ERR_STOP;
  }

  uint8_t* msg = buf;
  while (len >= 2) {
    uint8_t event = *msg++;
    uint8_t namelen = *msg++;
    if (len < (namelen + 2u)) {
      printf("vc: malformed device directory message\n");
      return ZX_ERR_STOP;
    }
    // add temporary nul
    uint8_t tmp = msg[namelen];
    msg[namelen] = 0;
    zx_status_t status = event_handler(event, reinterpret_cast<char*>(msg));
    if (status != ZX_OK) {
      return status;
    }
    msg[namelen] = tmp;
    msg += namelen;
    len -= (namelen + 2u);
  }
  return ZX_OK;
}

static zx_status_t vc_dc_dir_event_cb(async_dispatcher_t* dispatcher, async::Wait* wait,
                                      zx_status_t status, const zx_packet_signal_t* signal) {
#if BUILD_FOR_DISPLAY_TEST
  return ZX_ERR_NOT_SUPPORTED;
#else
  if (status != ZX_OK) {
    return status;
  }
  status = handle_device_dir_event(wait->object(), signal->observed, vc_dc_event);
  if (status != ZX_OK) {
    return status;
  }
  wait->Begin(dispatcher);
  return ZX_OK;
#endif
}

static void vc_find_display_controller() {
  auto endpoints = fidl::CreateEndpoints<fio::DirectoryWatcher>();
  if (endpoints.is_error()) {
    printf("vc: Failed to create dc watcher channel\n");
    return;
  }
  auto [client, server] = *std::move(endpoints);

  fdio_cpp::UnownedFdioCaller dir_caller(dc_dir_fd);

  auto result = fidl::WireCall(dir_caller.directory())
                    .Watch(fio::wire::WATCH_MASK_ALL, 0, server.TakeChannel());
  if (result.status() != ZX_OK) {
    printf("vc: Failed to watch dc directory\n");
    return;
  }

  ZX_DEBUG_ASSERT(!dc_wait.is_pending());

  dc_wait.set_object(client.TakeChannel().release());
  dc_wait.set_trigger(ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED);
  dc_wait.set_handler([](async_dispatcher_t* dispatcher, async::Wait* wait, zx_status_t status,
                         const zx_packet_signal_t* signal) {
    vc_dc_dir_event_cb(dispatcher, wait, status, signal);
  });

  zx_status_t status = dc_wait.Begin(dc_dispatcher);
  if (status != ZX_OK) {
    printf("vc: Failed to wait on dc directory\n");
  }
}

bool vc_display_init(async_dispatcher_t* dispatcher, bool hide_on_boot) {
  g_hide_on_boot = hide_on_boot;
  fbl::unique_fd fd(open(kDisplayControllerDir, O_DIRECTORY | O_RDONLY));
  if (!fd) {
    return false;
  }
  dc_dir_fd = fd.release();

  ZX_DEBUG_ASSERT(dc_dispatcher == nullptr);
  dc_dispatcher = dispatcher;
  vc_find_display_controller();

  return true;
}

bool vc_sysmem_connect() {
  auto sysmem_client = service::Connect<fuchsia_sysmem::Allocator>();
  if (sysmem_client.is_error()) {
    return false;
  }

  sysmem_allocator =
      std::make_unique<fidl::WireSyncClient<sysmem::Allocator>>(*std::move(sysmem_client));
  sysmem_allocator->SetDebugClientInfo(fidl::StringView::FromExternal(fsl::GetCurrentProcessName()),
                                       fsl::GetCurrentProcessKoid());
  return true;
}
