// 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_MANAGER2_H_
#define SRC_UI_SCENIC_LIB_DISPLAY_DISPLAY_MANAGER2_H_

#include <fuchsia/hardware/display/cpp/fidl.h>
#include <fuchsia/ui/display/cpp/fidl.h>
#include <lib/fidl/cpp/interface_ptr_set.h>
#include <lib/zx/channel.h>
#include <zircon/pixelformat.h>

#include <vector>

#include "src/lib/fxl/macros.h"
#include "src/lib/fxl/memory/weak_ptr.h"
#include "src/ui/scenic/lib/display/display_controller.h"
#include "src/ui/scenic/lib/display/display_controller_listener.h"

namespace scenic_impl {
namespace display {

// Implements the |fuchsia::ui::display::DisplayManager| protocol. Notifies protocol clients
// of new or removed displays and allows changing of display configuration. Every display is
// associated with a DisplayRef which can also be used as a parameter to other apis (e.g. Scenic).
// Additionally, allows an internal (within Scenic) client to claim the display and
class DisplayManager2 : public fuchsia::ui::display::DisplayManager {
 public:
  DisplayManager2();

  // |fuchsia::ui::display::DisplayManager|
  void AddDisplayListener(fidl::InterfaceHandle<fuchsia::ui::display::DisplayListener>
                              display_listener_interface_handle) override;

  // Remaining methods are not part of the FIDL protocol.

  // Called by initializing code whenever a new DisplayzController is discovered, or by tests.
  void AddDisplayController(
      std::shared_ptr<fuchsia::hardware::display::ControllerSyncPtr> controller,
      std::unique_ptr<DisplayControllerListener> controller_listener);

  DisplayControllerUniquePtr ClaimDisplay(zx_koid_t display_ref_koid);
  DisplayControllerUniquePtr ClaimFirstDisplayDeprecated();

  const fxl::WeakPtr<DisplayManager2> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }

  // For testing purposes only.
  const std::string& last_error() { return last_error_; }

  DisplayManager2(const DisplayManager2&) = delete;
  DisplayManager2(DisplayManager2&&) = delete;
  DisplayManager2& operator=(const DisplayManager2&) = delete;
  DisplayManager2& operator=(DisplayManager2&&) = delete;

 private:
  struct DisplayInfoPrivate {
    // |id| assigned by the DisplayController.
    uint64_t id = 0;

    zx_koid_t display_ref_koid = 0;

    std::vector<zx_pixel_format_t> pixel_formats;

    // Interface for the DisplayController that this display is connected to.
    std::shared_ptr<fuchsia::hardware::display::ControllerSyncPtr> controller;

    // Also stores the key version of the DisplayRef.
    fuchsia::ui::display::Info info;
  };

  // Internal data structure that holds the DisplayController interface and
  // associated info (listener, list of Displays).
  struct DisplayControllerPrivate {
    // If a a client has called ClaimDisplay(), this will be non-null and point
    // to the DisplayController passed to the client. This pointer is nulled
    // out by the custom deleter for the DisplayController.
    DisplayController* claimed_dc = nullptr;

    std::shared_ptr<fuchsia::hardware::display::ControllerSyncPtr> controller;
    std::unique_ptr<DisplayControllerListener> listener;
    std::vector<DisplayInfoPrivate> displays;

    // The latest value of the OnClientOwnershipChange event from the
    // display controller.
    bool has_ownership = false;
  };
  using DisplayControllerPrivateUniquePtr =
      std::unique_ptr<DisplayControllerPrivate, std::function<void(DisplayControllerPrivate*)>>;

  void RemoveOnInvalid(DisplayControllerPrivate* dc);
  void OnDisplaysChanged(DisplayControllerPrivate* dc,
                         std::vector<fuchsia::hardware::display::Info> displays_added,
                         std::vector<uint64_t> displays_removed);
  void OnDisplayOwnershipChanged(DisplayControllerPrivate* dc, bool has_ownership);

  std::tuple<DisplayControllerPrivate*, DisplayInfoPrivate*> FindDisplay(
      zx_koid_t display_ref_koid);
  DisplayControllerPrivate* FindDisplayControllerPrivate(DisplayController* dc);

  static DisplayInfoPrivate NewDisplayInfoPrivate(
      fuchsia::hardware::display::Info hardware_display_info,
      std::shared_ptr<fuchsia::hardware::display::ControllerSyncPtr> controller);
  static void InvokeDisplayAddedForListener(
      const fidl::InterfacePtr<fuchsia::ui::display::DisplayListener>& listener,
      const DisplayInfoPrivate& display_info_private);
  static void InvokeDisplayOwnershipChangedForListener(
      const fidl::InterfacePtr<fuchsia::ui::display::DisplayListener>& listener,
      DisplayControllerPrivate* dc, bool has_ownership);

  // Helper functions for lists of DisplayInfoPrivate.
  static bool HasDisplayWithId(const std::vector<DisplayManager2::DisplayInfoPrivate>& displays,
                               uint64_t display_id);

  static std::optional<DisplayManager2::DisplayInfoPrivate> RemoveDisplayWithId(
      std::vector<DisplayInfoPrivate>* displays, uint64_t display_id);

  std::vector<DisplayControllerPrivateUniquePtr> display_controllers_private_;
  fidl::InterfacePtrSet<fuchsia::ui::display::DisplayListener> display_listeners_;
  std::string last_error_;

  fxl::WeakPtrFactory<DisplayManager2> weak_factory_;  // must be last
};

}  // namespace display
}  // namespace scenic_impl

#endif  // SRC_UI_SCENIC_LIB_DISPLAY_DISPLAY_MANAGER2_H_
