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

#ifndef SRC_GRAPHICS_DISPLAY_DRIVERS_COORDINATOR_CLIENT_H_
#define SRC_GRAPHICS_DISPLAY_DRIVERS_COORDINATOR_CLIENT_H_

#include <fidl/fuchsia.hardware.display.types/cpp/wire.h>
#include <fidl/fuchsia.hardware.display/cpp/wire.h>
#include <fidl/fuchsia.sysmem/cpp/wire.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async/cpp/task.h>
#include <lib/fit/function.h>
#include <lib/inspect/cpp/inspect.h>
#include <lib/sync/completion.h>
#include <zircon/assert.h>
#include <zircon/compiler.h>
#include <zircon/types.h>

#include <cstdint>
#include <list>
#include <map>
#include <memory>
#include <type_traits>
#include <variant>
#include <vector>

#include <fbl/array.h>
#include <fbl/auto_lock.h>
#include <fbl/intrusive_double_list.h>
#include <fbl/ref_ptr.h>
#include <fbl/ring_buffer.h>
#include <fbl/vector.h>

#include "src/graphics/display/drivers/coordinator/capture-image.h"
#include "src/graphics/display/drivers/coordinator/client-id.h"
#include "src/graphics/display/drivers/coordinator/client-priority.h"
#include "src/graphics/display/drivers/coordinator/controller.h"
#include "src/graphics/display/drivers/coordinator/fence.h"
#include "src/graphics/display/drivers/coordinator/id-map.h"
#include "src/graphics/display/drivers/coordinator/image.h"
#include "src/graphics/display/drivers/coordinator/layer.h"
#include "src/graphics/display/drivers/coordinator/migration-util.h"
#include "src/graphics/display/lib/api-types-cpp/buffer-collection-id.h"
#include "src/graphics/display/lib/api-types-cpp/buffer-id.h"
#include "src/graphics/display/lib/api-types-cpp/config-stamp.h"
#include "src/graphics/display/lib/api-types-cpp/display-id.h"
#include "src/graphics/display/lib/api-types-cpp/driver-buffer-collection-id.h"
#include "src/graphics/display/lib/api-types-cpp/driver-layer-id.h"
#include "src/graphics/display/lib/api-types-cpp/event-id.h"
#include "src/graphics/display/lib/api-types-cpp/image-id.h"
#include "src/graphics/display/lib/api-types-cpp/vsync-ack-cookie.h"

namespace display {

// Almost-POD used by Client to manage display configuration. Public state is used by Controller.
class DisplayConfig : public IdMappable<std::unique_ptr<DisplayConfig>, DisplayId> {
 public:
  void InitializeInspect(inspect::Node* parent);

  bool apply_layer_change() {
    bool ret = pending_apply_layer_change_;
    pending_apply_layer_change_ = false;
    pending_apply_layer_change_property_.Set(false);
    return ret;
  }

  // Discards all the pending config (except for pending layers lists)
  // of a Display's `config`.
  //
  // The display pending layers' pending config must be discarded before
  // `DiscardNonLayerPendingConfig()` is called.
  void DiscardNonLayerPendingConfig();

  int current_layer_count() const { return static_cast<int>(current_.layer_count); }
  const display_config_t* current_config() const { return &current_; }
  const fbl::DoublyLinkedList<LayerNode*>& get_current_layers() const { return current_layers_; }

 private:
  display_config_t current_;
  display_config_t pending_;

  bool pending_layer_change_;
  bool pending_apply_layer_change_;
  fbl::DoublyLinkedList<LayerNode*> pending_layers_;
  fbl::DoublyLinkedList<LayerNode*> current_layers_;

  fbl::Array<CoordinatorPixelFormat> pixel_formats_;

  bool display_config_change_ = false;

  friend Client;
  friend ClientProxy;

  inspect::Node node_;
  inspect::BoolProperty pending_layer_change_property_;
  inspect::BoolProperty pending_apply_layer_change_property_;
};

// Helper class for sending events using the same API, regardless if |Client| is
// bound to a FIDL connection. This object either holds a binding reference or a
// |ServerEnd| that owns the channel, both of which allows sending events
// without unsafe channel borrowing.
class DisplayControllerBindingState {
  using Protocol = fuchsia_hardware_display::Coordinator;

 public:
  // Constructs an invalid binding state. The user must populate it with an
  // active binding reference or event sender before events could be sent.
  DisplayControllerBindingState() = default;

  explicit DisplayControllerBindingState(fidl::ServerEnd<Protocol> server_end)
      : binding_state_(std::move(server_end)) {}

  // Invokes |fn| with an polymorphic object that may be used to send events
  // in |Protocol|.
  //
  // |fn| must be a templated lambda that calls
  // |fidl::WireSendEvent(arg)->OnSomeEvent| to send |OnSomeEvent| event, and
  // returns a |fidl::Status|.
  template <typename EventSenderConsumer>
  fidl::Status SendEvents(EventSenderConsumer&& fn) {
    return std::visit(
        [&](auto&& arg) -> fidl::Status {
          using T = std::decay_t<decltype(arg)>;
          if constexpr (std::is_same_v<T, fidl::ServerBindingRef<Protocol>>) {
            return fn(arg);
          }
          if constexpr (std::is_same_v<T, fidl::ServerEnd<Protocol>>) {
            return fn(arg);
          }
          ZX_PANIC("Invalid display controller binding state");
        },
        binding_state_);
  }

  // Sets this object into the bound state, i.e. the server is handling FIDL
  // messages, and the connect may be managed through |binding|.
  void SetBound(fidl::ServerBindingRef<Protocol> binding) { binding_state_ = std::move(binding); }

  // If the object is in the bound state, schedules it to be unbound.
  void Unbind() {
    if (auto ref = std::get_if<fidl::ServerBindingRef<Protocol>>(&binding_state_)) {
      // Note that |binding_state_| will remain in the
      // |fidl::ServerBindingRef<Protocol>| variant, and future attempts to
      // send events will fail at runtime. This should be okay since the client
      // is shutting down when unbinding happens.
      ref->Unbind();
    }
  }

 private:
  std::variant<std::monostate, fidl::ServerBindingRef<Protocol>, fidl::ServerEnd<Protocol>>
      binding_state_;
};

// Manages the state associated with a display coordinator client connection.
//
// This class is not thread-safe. After initialization, all methods must be
// executed on the same thread.
class Client final : public fidl::WireServer<fuchsia_hardware_display::Coordinator> {
 public:
  // |controller| must outlive this and |proxy|.
  Client(Controller* controller, ClientProxy* proxy, ClientPriority priority, ClientId client_id);

  // This is used for testing
  Client(Controller* controller, ClientProxy* proxy, ClientPriority priority, ClientId client_id,
         fidl::ServerEnd<fuchsia_hardware_display::Coordinator> server_end);

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

  ~Client() override;

  fpromise::result<fidl::ServerBindingRef<fuchsia_hardware_display::Coordinator>, zx_status_t> Init(
      fidl::ServerEnd<fuchsia_hardware_display::Coordinator> server_end);

  void OnDisplaysChanged(cpp20::span<const DisplayId> added_display_ids,
                         cpp20::span<const DisplayId> removed_display_ids);
  void SetOwnership(bool is_owner);
  void ApplyConfig();

  void OnFenceFired(FenceReference* fence);

  void TearDown();
  // This is used for testing
  void TearDownTest();

  bool IsValid() const { return running_; }
  ClientId id() const { return id_; }
  ClientPriority priority() const { return priority_; }
  void CaptureCompleted();

  uint8_t GetMinimumRgb() const { return client_minimum_rgb_; }

  // Test helpers
  size_t TEST_imported_images_count() const { return images_.size(); }

  void CancelFidlBind() { binding_state_.Unbind(); }

  DisplayControllerBindingState& binding_state() { return binding_state_; }

  // Used for testing
  sync_completion_t* fidl_unbound() { return &fidl_unbound_; }
  VsyncAckCookie LatestAckedCookie() const { return acked_cookie_; }

  // fidl::WireServer<fuchsia_hardware_display::Coordinator> overrides:
  void ImportImage(ImportImageRequestView request, ImportImageCompleter::Sync& _completer) override;
  void ReleaseImage(ReleaseImageRequestView request,
                    ReleaseImageCompleter::Sync& _completer) override;
  void ImportEvent(ImportEventRequestView request, ImportEventCompleter::Sync& _completer) override;
  void ReleaseEvent(ReleaseEventRequestView request,
                    ReleaseEventCompleter::Sync& _completer) override;
  void CreateLayer(CreateLayerCompleter::Sync& _completer) override;
  void DestroyLayer(DestroyLayerRequestView request,
                    DestroyLayerCompleter::Sync& _completer) override;
  void SetDisplayMode(SetDisplayModeRequestView request,
                      SetDisplayModeCompleter::Sync& _completer) override;
  void SetDisplayColorConversion(SetDisplayColorConversionRequestView request,
                                 SetDisplayColorConversionCompleter::Sync& _completer) override;
  void SetDisplayLayers(SetDisplayLayersRequestView request,
                        SetDisplayLayersCompleter::Sync& _completer) override;
  void SetLayerPrimaryConfig(SetLayerPrimaryConfigRequestView request,
                             SetLayerPrimaryConfigCompleter::Sync& _completer) override;
  void SetLayerPrimaryPosition(SetLayerPrimaryPositionRequestView request,
                               SetLayerPrimaryPositionCompleter::Sync& _completer) override;
  void SetLayerPrimaryAlpha(SetLayerPrimaryAlphaRequestView request,
                            SetLayerPrimaryAlphaCompleter::Sync& _completer) override;
  void SetLayerColorConfig(SetLayerColorConfigRequestView request,
                           SetLayerColorConfigCompleter::Sync& _completer) override;
  void SetLayerImage(SetLayerImageRequestView request,
                     SetLayerImageCompleter::Sync& _completer) override;
  void CheckConfig(CheckConfigRequestView request, CheckConfigCompleter::Sync& _completer) override;
  void ApplyConfig(ApplyConfigCompleter::Sync& _completer) override;
  void ApplyConfig2(ApplyConfig2RequestView request,
                    ApplyConfigCompleter::Sync& _completer) override {
    ZX_PANIC("Not Implemented");
  }
  void GetLatestAppliedConfigStamp(GetLatestAppliedConfigStampCompleter::Sync& _completer) override;
  void EnableVsync(EnableVsyncRequestView request, EnableVsyncCompleter::Sync& _completer) override;
  void SetVirtconMode(SetVirtconModeRequestView request,
                      SetVirtconModeCompleter::Sync& _completer) override;
  void ImportBufferCollection(ImportBufferCollectionRequestView request,
                              ImportBufferCollectionCompleter::Sync& _completer) override;
  void SetBufferCollectionConstraints(
      SetBufferCollectionConstraintsRequestView request,
      SetBufferCollectionConstraintsCompleter::Sync& _completer) override;
  void ReleaseBufferCollection(ReleaseBufferCollectionRequestView request,
                               ReleaseBufferCollectionCompleter::Sync& _completer) override;

  void IsCaptureSupported(IsCaptureSupportedCompleter::Sync& _completer) override;

  void StartCapture(StartCaptureRequestView request,
                    StartCaptureCompleter::Sync& _completer) override;

  void AcknowledgeVsync(AcknowledgeVsyncRequestView request,
                        AcknowledgeVsyncCompleter::Sync& _completer) override;

  void SetMinimumRgb(SetMinimumRgbRequestView request,
                     SetMinimumRgbCompleter::Sync& _completer) override;

  void SetDisplayPower(SetDisplayPowerRequestView request,
                       SetDisplayPowerCompleter::Sync& _completer) override;

 private:
  // Cleans up states of all current Images.
  // Returns true if any current layer has been modified.
  bool CleanUpAllImages();

  // Cleans up layer state associated with an Image. `image` must be valid.
  // Returns true if a current layer has been modified.
  bool CleanUpImage(Image& image);
  void CleanUpCaptureImage(ImageId id);

  // Displays' pending layers list may have been changed by pending
  // SetDisplayLayers() operations.
  //
  // Restores the pending layer lists of all the Displays to their current
  // (applied) layer list state respectively, undoing all pending changes to
  // the layer lists.
  void SetAllConfigPendingLayersToCurrentLayers();

  // `fuchsia.hardware.display/Coordinator.ImportImage()` helper for display
  // images.
  //
  // `image_id` must be unused and `image_metadata` contains metadata for an
  // image used for display.
  zx_status_t ImportImageForDisplay(const ImageMetadata& image_metadata, BufferId buffer_id,
                                    ImageId image_id);

  // `fuchsia.hardware.display/Coordinator.ImportImage()` helper for capture
  // images.
  //
  // `image_id` must be unused and `image_metadata` contains metadata for an
  // image used for capture.
  zx_status_t ImportImageForCapture(const ImageMetadata& image_metadata, BufferId buffer_id,
                                    ImageId image_id);

  // Discards all the pending config on all Displays and Layers.
  void DiscardConfig();

  Controller* const controller_;
  ClientProxy* const proxy_;
  const ClientPriority priority_;
  const ClientId id_;
  bool running_;

  Image::Map images_;
  CaptureImage::Map capture_images_;

  DisplayConfig::Map configs_;
  bool pending_config_valid_ = false;
  bool is_owner_ = false;

  // A counter for the number of times the client has successfully applied
  // a configuration. This does not account for changes due to waiting images.
  uint32_t client_apply_count_ = 0;
  ConfigStamp latest_config_stamp_ = kInvalidConfigStamp;

  // This is the client's clamped RGB value.
  uint8_t client_minimum_rgb_ = 0;
  sync_completion_t fidl_unbound_;

  struct Collections {
    // The BufferCollection ID used in fuchsia.hardware.display.Controller
    // protocol.
    display::DriverBufferCollectionId driver_buffer_collection_id;
  };
  std::map<display::BufferCollectionId, Collections> collection_map_;

  FenceCollection fences_;

  Layer::Map layers_;

  // TODO(fxbug.com/129082): Move to Controller, so values issued using this
  // counter are globally unique. Do not pass to DriverLayerId values to drivers
  // until this issue is fixed.
  DriverLayerId next_driver_layer_id = DriverLayerId(1);

  void NotifyDisplaysChanged(const int32_t* displays_added, uint32_t added_count,
                             const int32_t* displays_removed, uint32_t removed_count);
  bool CheckConfig(fuchsia_hardware_display_types::wire::ConfigResult* res,
                   std::vector<fuchsia_hardware_display::wire::ClientCompositionOp>* ops);

  // The state of the FIDL binding. See comments on
  // |DisplayControllerBindingState|.
  DisplayControllerBindingState binding_state_;

  // Capture related book keeping
  EventId capture_fence_id_ = kInvalidEventId;

  // Points to the image whose contents is modified by the current capture.
  //
  // Invalid when no is capture in progress.
  ImageId current_capture_image_id_ = kInvalidImageId;

  // Tracks an image released by the client while used by a capture.
  //
  // The coordinator must ensure that an image remains valid while a display
  // engine is writing to it. If a client attempts to release the image used by
  // an in-progress capture, we defer the release operation until the capture
  // completes. The deferred release is tracked here.
  ImageId pending_release_capture_image_id_ = kInvalidImageId;

  VsyncAckCookie acked_cookie_ = kInvalidVsyncAckCookie;
};

// ClientProxy manages interactions between its Client instance and the
// controller. Methods on this class are thread safe.
class ClientProxy {
 public:
  // `client_id` is assigned by the Controller to distinguish clients.
  ClientProxy(Controller* controller, ClientPriority client_priority, ClientId client_id,
              fit::function<void()> on_client_dead);

  // This is used for testing
  ClientProxy(Controller* controller, ClientPriority client_priority, ClientId client_id,
              fidl::ServerEnd<fuchsia_hardware_display::Coordinator> server_end);

  ~ClientProxy();
  zx_status_t Init(inspect::Node* parent_node,
                   fidl::ServerEnd<fuchsia_hardware_display::Coordinator> server_end);

  // Schedule a task on the controller loop to close this ClientProxy and
  // have it be freed.
  void CloseOnControllerLoop();

  // Requires holding controller_->mtx() lock
  zx_status_t OnDisplayVsync(DisplayId display_id, zx_time_t timestamp,
                             ConfigStamp controller_stamp);
  void OnDisplaysChanged(cpp20::span<const DisplayId> added_display_ids,
                         cpp20::span<const DisplayId> removed_display_ids);
  void SetOwnership(bool is_owner);
  void ReapplyConfig();
  zx_status_t OnCaptureComplete();

  void EnableVsync(bool enable) {
    fbl::AutoLock lock(&mtx_);
    enable_vsync_ = enable;
  }

  void EnableCapture(bool enable) {
    fbl::AutoLock lock(&mtx_);
    enable_capture_ = enable;
  }
  void OnClientDead();

  // This function restores client configurations that are not part of
  // the standard configuration. These configurations are typically one-time
  // settings that need to get restored once client takes control again.
  void ReapplySpecialConfigs();

  ClientId client_id() const { return handler_.id(); }

  inspect::Node& node() { return node_; }

  struct ConfigStampPair {
    ConfigStamp controller_stamp;
    ConfigStamp client_stamp;
  };
  std::list<ConfigStampPair>& pending_applied_config_stamps() {
    return pending_applied_config_stamps_;
  }

  // Add a new mapping entry from |stamps.controller_stamp| to |stamp.config_stamp|.
  // Controller should guarantee that |stamps.controller_stamp| is strictly
  // greater than existing pending controller stamps.
  void UpdateConfigStampMapping(ConfigStampPair stamps);

  // This is used for testing
  void CloseTest();

  // Test helpers
  size_t TEST_imported_images_count() const { return handler_.TEST_imported_images_count(); }

  // Define these constants here so we can access it for test

  static constexpr uint32_t kVsyncBufferSize = 10;

  // Maximum number of vsync messages sent before an acknowledgement is required.
  // Half of this limit is provided to clients as part of display info. Assuming a
  // frame rate of 60hz, clients will be required to acknowledge at least once a second
  // and driver will stop sending messages after 2 seconds of no acknowledgement
  static constexpr uint32_t kMaxVsyncMessages = 120;
  static constexpr uint32_t kVsyncMessagesWatermark = (kMaxVsyncMessages / 2);
  // At the moment, maximum image handles returned by any driver is 4 which is
  // equal to number of hardware layers. 8 should be more than enough to allow for
  // a simple statically allocated array of image_ids for vsync events that are being
  // stored due to client non-acknowledgement.
  static constexpr uint32_t kMaxImageHandles = 8;

 private:
  friend IntegrationTest;

  mtx_t mtx_;
  Controller* const controller_;

  Client handler_;
  bool enable_vsync_ __TA_GUARDED(&mtx_) = false;
  bool enable_capture_ __TA_GUARDED(&mtx_) = false;

  mtx_t task_mtx_;
  std::vector<std::unique_ptr<async::Task>> client_scheduled_tasks_ __TA_GUARDED(task_mtx_);

  // This variable is used to limit the number of errors logged in case of channel oom error
  static constexpr uint32_t kChannelOomPrintFreq = 600;  // 1 per 10 seconds (assuming 60fps)
  uint32_t chn_oom_print_freq_ = 0;
  uint64_t total_oom_errors_ = 0;

  struct VsyncMessageData {
    DisplayId display_id;
    zx_time_t timestamp;
    ConfigStamp config_stamp;
  };

  fbl::RingBuffer<VsyncMessageData, kVsyncBufferSize> buffered_vsync_messages_;
  VsyncAckCookie initial_cookie_ = VsyncAckCookie(0);
  VsyncAckCookie cookie_sequence_ = VsyncAckCookie(0);

  uint64_t number_of_vsyncs_sent_ = 0;
  VsyncAckCookie last_cookie_sent_ = kInvalidVsyncAckCookie;
  bool acknowledge_request_sent_ = false;

  fit::function<void()> on_client_dead_;

  // Mapping from controller_stamp to client_stamp for all configurations that
  // are already applied and pending to be presented on the display.
  // Ordered by |controller_stamp_| in increasing order.
  std::list<ConfigStampPair> pending_applied_config_stamps_;

  inspect::Node node_;
  inspect::BoolProperty is_owner_property_;
};

}  // namespace display

#endif  // SRC_GRAPHICS_DISPLAY_DRIVERS_COORDINATOR_CLIENT_H_
