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

#ifndef SRC_UI_SCENIC_LIB_DISPLAY_DISPLAY_CONTROLLER_LISTENER_H_
#define SRC_UI_SCENIC_LIB_DISPLAY_DISPLAY_CONTROLLER_LISTENER_H_

#include <fuchsia/hardware/display/cpp/fidl.h>
#include <lib/async/cpp/wait.h>
#include <lib/fit/function.h>
#include <lib/zx/channel.h>
#include <lib/zx/event.h>

#include "lib/fidl/cpp/synchronous_interface_ptr.h"

namespace scenic_impl {
namespace display {

// DisplayControllerListener wraps a |fuchsia::hardware::display::Controller| interface, allowing
// registering for event callbacks.
class DisplayControllerListener {
 public:
  using OnDisplaysChangedCallback = std::function<void(
      std::vector<fuchsia::hardware::display::Info> added, std::vector<uint64_t> removed)>;
  using OnClientOwnershipChangeCallback = std::function<void(bool has_ownership)>;
  using OnVsyncCallback = std::function<void(uint64_t display_id, uint64_t timestamp,
                                             std::vector<uint64_t> images, uint64_t cookie)>;

  // Binds to a Display fuchsia::hardware::display::Controller with channels |device| and
  // with display controller |controller|. |controller_handle| is the raw handle wrapped by
  // |controller|; unfortunately it must be passed separately since there's no  way to get it from
  // |controller|.
  //
  // If |device| or |controller_handle| is invalid, or |controller| is not bound, this instance is
  // invalid.
  DisplayControllerListener(
      zx::channel device_channel,
      std::shared_ptr<fuchsia::hardware::display::ControllerSyncPtr> controller,
      zx_handle_t controller_handle);
  ~DisplayControllerListener();

  // If any of the channels gets disconnected, |on_invalid| is invoked and this object becomes
  // invalid.
  void InitializeCallbacks(fit::closure on_invalid,
                           OnDisplaysChangedCallback on_displays_changed_cb,
                           OnClientOwnershipChangeCallback on_client_ownership_change_cb);

  // Removes all callbacks. Once this is done, there is no way to re-initialize the callbacks.
  void ClearCallbacks();

  void SetOnVsyncCallback(OnVsyncCallback vsync_callback);

  // Whether the connection to the display controller driver is still valid.
  bool valid() { return valid_; }

 private:
  void OnPeerClosedAsync(async_dispatcher_t* dispatcher, async::WaitBase* self, zx_status_t status,
                         const zx_packet_signal_t* signal);
  void OnEventMsgAsync(async_dispatcher_t* dispatcher, async::WaitBase* self, zx_status_t status,
                       const zx_packet_signal_t* signal);

  // The display controller driver binding.
  std::shared_ptr<fuchsia::hardware::display::ControllerSyncPtr> controller_;

  // True if we're connected to |controller_|.
  bool valid_ = false;

  // |controller_| owns |controller_channel_handle_|, but save its handle here for use.
  zx_handle_t controller_channel_handle_ = 0;

  // |device_channel_| needs to be kept alive to stay connected to |controller_|.
  zx::channel device_channel_;

  // Callback to invoke if we disconnect from |controller_|.
  fit::closure on_invalid_cb_ = nullptr;

  // True if InitializeCallbacks was called; it can only be called once.
  bool initialized_callbacks_ = false;

  // Waits for a ZX_CHANNEL_READABLE signal.
  async::WaitMethod<DisplayControllerListener, &DisplayControllerListener::OnEventMsgAsync>
      wait_event_msg_{this};
  // Wait for a ZX_PEER_CLOSED signal.
  async::WaitMethod<DisplayControllerListener, &DisplayControllerListener::OnPeerClosedAsync>
      wait_device_closed_{this};
  async::WaitMethod<DisplayControllerListener, &DisplayControllerListener::OnPeerClosedAsync>
      wait_controller_closed_{this};

  // Used for dispatching events that we receive over the controller channel.
  // TODO(FIDL-183): Resolve this hack when synchronous interfaces support events.
  fidl::InterfacePtr<fuchsia::hardware::display::Controller> event_dispatcher_;
};

}  // namespace display
}  // namespace scenic_impl

#endif  // SRC_UI_SCENIC_LIB_DISPLAY_DISPLAY_CONTROLLER_LISTENER_H_
