/*
 *  Copyright 2022 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_SCREENCAST_PORTAL_H_
#define MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_SCREENCAST_PORTAL_H_

#include <gio/gio.h>

#include <string>

#include "modules/desktop_capture/desktop_capture_types.h"
#include "modules/desktop_capture/linux/wayland/screen_capture_portal_interface.h"
#include "modules/portal/portal_request_response.h"
#include "modules/portal/xdg_desktop_portal_utils.h"
#include "modules/portal/xdg_session_details.h"

namespace webrtc {

class RTC_EXPORT ScreenCastPortal
    : public xdg_portal::ScreenCapturePortalInterface {
 public:
  using ProxyRequestResponseHandler = void (*)(GObject* object,
                                               GAsyncResult* result,
                                               gpointer user_data);

  using SourcesRequestResponseSignalHandler =
      void (*)(GDBusConnection* connection,
               const char* sender_name,
               const char* object_path,
               const char* interface_name,
               const char* signal_name,
               GVariant* parameters,
               gpointer user_data);

  // Values are set based on cursor mode property in
  // xdg-desktop-portal/screencast
  // https://github.com/flatpak/xdg-desktop-portal/blob/master/data/org.freedesktop.portal.ScreenCast.xml
  enum class CursorMode : uint32_t {
    // Mouse cursor will not be included in any form
    kHidden = 0b01,
    // Mouse cursor will be part of the screen content
    kEmbedded = 0b10,
    // Mouse cursor information will be send separately in form of metadata
    kMetadata = 0b100
  };

  // Values are set based on persist mode property in
  // xdg-desktop-portal/screencast
  // https://github.com/flatpak/xdg-desktop-portal/blob/master/data/org.freedesktop.portal.ScreenCast.xml
  enum class PersistMode : uint32_t {
    // Do not allow to restore stream
    kDoNotPersist = 0b00,
    // The restore token is valid as long as the application is alive. It's
    // stored in memory and revoked when the application closes its DBus
    // connection
    kTransient = 0b01,
    // The restore token is stored in disk and is valid until the user manually
    // revokes it
    kPersistent = 0b10
  };

  // Interface that must be implemented by the ScreenCastPortal consumers.
  class PortalNotifier {
   public:
    virtual void OnScreenCastRequestResult(xdg_portal::RequestResponse result,
                                           uint32_t stream_node_id,
                                           int fd) = 0;
    virtual void OnScreenCastSessionClosed() = 0;

   protected:
    PortalNotifier() = default;
    virtual ~PortalNotifier() = default;
  };

  ScreenCastPortal(CaptureType type, PortalNotifier* notifier);
  ScreenCastPortal(CaptureType type,
                   PortalNotifier* notifier,
                   ProxyRequestResponseHandler proxy_request_response_handler,
                   SourcesRequestResponseSignalHandler
                       sources_request_response_signal_handler,
                   gpointer user_data,
                   // TODO(chromium:1291247): Remove the default option once
                   // downstream has been adjusted.
                   bool prefer_cursor_embedded = false);

  ~ScreenCastPortal();

  // Initialize ScreenCastPortal with series of DBus calls where we try to
  // obtain all the required information, like PipeWire file descriptor and
  // PipeWire stream node ID.
  //
  // The observer will return whether the communication with xdg-desktop-portal
  // was successful and only then you will be able to get all the required
  // information in order to continue working with PipeWire.
  void Start() override;
  void Stop() override;
  xdg_portal::SessionDetails GetSessionDetails() override;

  // Method to notify the reason for failure of a portal request.
  void OnPortalDone(xdg_portal::RequestResponse result) override;

  // Sends a create session request to the portal.
  void RequestSession(GDBusProxy* proxy) override;

  // Set of methods leveraged by remote desktop portal to setup a common session
  // with screen cast portal.
  void SetSessionDetails(const xdg_portal::SessionDetails& session_details);
  uint32_t pipewire_stream_node_id();
  void SourcesRequest();
  void OpenPipeWireRemote();

  // ScreenCast specific methods for stream restoration
  void SetPersistMode(ScreenCastPortal::PersistMode mode);
  void SetRestoreToken(const std::string& token);
  std::string RestoreToken() const;

 private:
  // Values are set based on source type property in
  // xdg-desktop-portal/screencast
  // https://github.com/flatpak/xdg-desktop-portal/blob/master/data/org.freedesktop.portal.ScreenCast.xml
  enum class CaptureSourceType : uint32_t {
    kScreen = 0b01,
    kWindow = 0b10,
    kAnyScreenContent = kScreen | kWindow
  };
  static CaptureSourceType ToCaptureSourceType(CaptureType type);

  PortalNotifier* notifier_;

  // A PipeWire stream ID of stream we will be connecting to
  uint32_t pw_stream_node_id_ = 0;
  // A file descriptor of PipeWire socket
  int pw_fd_ = -1;
  // Restore token that can be used to restore previous session
  std::string restore_token_;

  CaptureSourceType capture_source_type_ =
      ScreenCastPortal::CaptureSourceType::kScreen;

  CursorMode cursor_mode_ = CursorMode::kMetadata;

  PersistMode persist_mode_ = ScreenCastPortal::PersistMode::kDoNotPersist;

  ProxyRequestResponseHandler proxy_request_response_handler_;
  SourcesRequestResponseSignalHandler sources_request_response_signal_handler_;
  gpointer user_data_;

  GDBusConnection* connection_ = nullptr;
  GDBusProxy* proxy_ = nullptr;
  GCancellable* cancellable_ = nullptr;
  std::string portal_handle_;
  std::string session_handle_;
  std::string sources_handle_;
  std::string start_handle_;
  guint session_request_signal_id_ = 0;
  guint sources_request_signal_id_ = 0;
  guint start_request_signal_id_ = 0;
  guint session_closed_signal_id_ = 0;

  void UnsubscribeSignalHandlers();
  static void OnProxyRequested(GObject* object,
                               GAsyncResult* result,
                               gpointer user_data);
  static void OnSessionRequested(GDBusProxy* proxy,
                                 GAsyncResult* result,
                                 gpointer user_data);
  static void OnSessionRequestResponseSignal(GDBusConnection* connection,
                                             const char* sender_name,
                                             const char* object_path,
                                             const char* interface_name,
                                             const char* signal_name,
                                             GVariant* parameters,
                                             gpointer user_data);
  static void OnSessionClosedSignal(GDBusConnection* connection,
                                    const char* sender_name,
                                    const char* object_path,
                                    const char* interface_name,
                                    const char* signal_name,
                                    GVariant* parameters,
                                    gpointer user_data);
  static void OnSourcesRequested(GDBusProxy* proxy,
                                 GAsyncResult* result,
                                 gpointer user_data);
  static void OnSourcesRequestResponseSignal(GDBusConnection* connection,
                                             const char* sender_name,
                                             const char* object_path,
                                             const char* interface_name,
                                             const char* signal_name,
                                             GVariant* parameters,
                                             gpointer user_data);

  void StartRequest();
  static void OnStartRequested(GDBusProxy* proxy,
                               GAsyncResult* result,
                               gpointer user_data);
  static void OnStartRequestResponseSignal(GDBusConnection* connection,
                                           const char* sender_name,
                                           const char* object_path,
                                           const char* interface_name,
                                           const char* signal_name,
                                           GVariant* parameters,
                                           gpointer user_data);

  static void OnOpenPipeWireRemoteRequested(GDBusProxy* proxy,
                                            GAsyncResult* result,
                                            gpointer user_data);
};

}  // namespace webrtc

#endif  // MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_SCREENCAST_PORTAL_H_
