// Copyright 2020 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 "src/ui/lib/display/hardware_display_controller_provider_impl.h"

#include <fcntl.h>
#include <fuchsia/hardware/display/c/fidl.h>
#include <lib/fdio/cpp/caller.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/status.h>

#include <cstdint>

#include "src/lib/fsl/io/device_watcher.h"

namespace ui_display {

static const std::string kDisplayDir = "/dev/class/display-controller";

HardwareDisplayControllerProviderImpl::HardwareDisplayControllerProviderImpl(
    sys::ComponentContext* app_context) {
  app_context->outgoing()->AddPublicService(bindings_.GetHandler(this));
}

// |fuchsia::hardware::display::Provider|.
void HardwareDisplayControllerProviderImpl::OpenController(
    zx::channel device, ::fidl::InterfaceRequest<fuchsia::hardware::display::Controller> request,
    OpenControllerCallback callback) {
  // Watcher's lifetime needs to be at most as long as the lifetime of |this|,
  // and otherwise as long as the lifetime of |callback|.  |this| will own
  // the references to outstanding watchers, and each watcher will notify |this|
  // when it is done, so that |this| can remove a reference to it.
  static uint64_t last_id = 0;
  const uint64_t id = ++last_id;

  std::unique_ptr<fsl::DeviceWatcher> watcher = fsl::DeviceWatcher::Create(
      kDisplayDir,
      [id, holders = &holders_, device = std::move(device), request = std::move(request),
       callback = std::move(callback)](int dir_fd, std::string filename) mutable {
        // Get display info.
        std::string path = kDisplayDir + "/" + filename;

        FX_LOGS(INFO) << "Found display controller at path: " << path << ".";
        fbl::unique_fd fd(open(path.c_str(), O_RDWR));
        if (!fd.is_valid()) {
          FX_LOGS(ERROR) << "Failed to open display_controller at path: " << path
                         << " (errno: " << errno << " " << strerror(errno) << ")";

          // We could try to match the value of the C "errno" macro to the closest ZX error, but
          // this would give rise to many corner cases.  We never expect this to fail anyway, since
          // |filename| is given to us by the device watcher.
          callback(ZX_ERR_INTERNAL);
          return;
        }

        // TODO(fxbug.dev/57269): it would be nice to simply pass |callback| asynchronously into
        // OpenController(), rather than blocking on a synchronous call.  However, it is non-trivial
        // to do so, so for now we use a blocking call to proxy the request.
        fdio_cpp::FdioCaller caller(std::move(fd));
        zx_status_t status = ZX_OK;
        zx_status_t fidl_status = fuchsia_hardware_display_ProviderOpenController(
            caller.borrow_channel(), device.release(), request.TakeChannel().release(), &status);
        if (fidl_status != ZX_OK) {
          FX_LOGS(ERROR) << "Failed to call service handle: " << zx_status_get_string(fidl_status);

          // There's not a clearly-better value to return here.  Returning the FIDL error would be
          // somewhat unexpected, since the caller wouldn't receive it as a FIDL status, rather as
          // the return value of a "successful" method invocation.
          callback(ZX_ERR_INTERNAL);
          return;
        }
        if (status != ZX_OK) {
          FX_LOGS(ERROR) << "Failed to open display controller : " << zx_status_get_string(status);
          callback(status);
          return;
        }

        callback(status);

        // We no longer need |this| to store this closure, remove it. Do not do
        // any work after this point.
        holders->erase(id);
      });
  holders_[id] = std::move(watcher);
}

void HardwareDisplayControllerProviderImpl::BindDisplayProvider(
    fidl::InterfaceRequest<fuchsia::hardware::display::Provider> request) {
  bindings_.AddBinding(this, std::move(request));
}

}  // namespace ui_display
