/*
 *  Copyright (c) 2023 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.
 */

#include "modules/video_capture/linux/camera_portal.h"

#include <gio/gio.h>
#include <gio/gunixfdlist.h>

#include "modules/portal/pipewire_utils.h"
#include "modules/portal/xdg_desktop_portal_utils.h"

namespace webrtc {

using xdg_portal::RequestResponse;
using xdg_portal::RequestResponseFromPortalResponse;
using xdg_portal::RequestSessionProxy;

constexpr char kCameraInterfaceName[] = "org.freedesktop.portal.Camera";

class CameraPortalPrivate {
 public:
  explicit CameraPortalPrivate(CameraPortal::PortalNotifier* notifier);
  ~CameraPortalPrivate();

  void Start();

 private:
  void OnPortalDone(xdg_portal::RequestResponse result,
                    int fd = kInvalidPipeWireFd);

  static void OnProxyRequested(GObject* object,
                               GAsyncResult* result,
                               gpointer user_data);
  void ProxyRequested(GDBusProxy* proxy);

  static void OnAccessResponse(GDBusProxy* proxy,
                               GAsyncResult* result,
                               gpointer user_data);
  static void OnResponseSignalEmitted(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 OnOpenResponse(GDBusProxy* proxy,
                             GAsyncResult* result,
                             gpointer user_data);

  CameraPortal::PortalNotifier* notifier_ = nullptr;

  GDBusConnection* connection_ = nullptr;
  GDBusProxy* proxy_ = nullptr;
  GCancellable* cancellable_ = nullptr;
  guint access_request_signal_id_ = 0;
};

CameraPortalPrivate::CameraPortalPrivate(CameraPortal::PortalNotifier* notifier)
    : notifier_(notifier) {}

CameraPortalPrivate::~CameraPortalPrivate() {
  if (access_request_signal_id_) {
    g_dbus_connection_signal_unsubscribe(connection_,
                                         access_request_signal_id_);
    access_request_signal_id_ = 0;
  }
  if (cancellable_) {
    g_cancellable_cancel(cancellable_);
    g_object_unref(cancellable_);
    cancellable_ = nullptr;
  }
  if (proxy_) {
    g_object_unref(proxy_);
    proxy_ = nullptr;
    connection_ = nullptr;
  }
}

void CameraPortalPrivate::Start() {
  cancellable_ = g_cancellable_new();
  Scoped<GError> error;
  RequestSessionProxy(kCameraInterfaceName, OnProxyRequested, cancellable_,
                      this);
}

// static
void CameraPortalPrivate::OnProxyRequested(GObject* gobject,
                                           GAsyncResult* result,
                                           gpointer user_data) {
  CameraPortalPrivate* that = static_cast<CameraPortalPrivate*>(user_data);
  Scoped<GError> error;
  GDBusProxy* proxy = g_dbus_proxy_new_finish(result, error.receive());
  if (!proxy) {
    // Ignore the error caused by user cancelling the request via `cancellable_`
    if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
      return;
    RTC_LOG(LS_ERROR) << "Failed to get a proxy for the portal: "
                      << error->message;
    that->OnPortalDone(RequestResponse::kError);
    return;
  }

  RTC_LOG(LS_VERBOSE) << "Successfully created proxy for the portal.";
  that->ProxyRequested(proxy);
}

void CameraPortalPrivate::ProxyRequested(GDBusProxy* proxy) {
  GVariantBuilder builder;
  Scoped<char> variant_string;
  std::string access_handle;

  proxy_ = proxy;
  connection_ = g_dbus_proxy_get_connection(proxy);

  g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
  variant_string =
      g_strdup_printf("capture%d", g_random_int_range(0, G_MAXINT));
  g_variant_builder_add(&builder, "{sv}", "handle_token",
                        g_variant_new_string(variant_string.get()));

  access_handle =
      xdg_portal::PrepareSignalHandle(variant_string.get(), connection_);
  access_request_signal_id_ = xdg_portal::SetupRequestResponseSignal(
      access_handle.c_str(), OnResponseSignalEmitted, this, connection_);

  RTC_LOG(LS_VERBOSE) << "Requesting camera access from the portal.";
  g_dbus_proxy_call(proxy_, "AccessCamera", g_variant_new("(a{sv})", &builder),
                    G_DBUS_CALL_FLAGS_NONE, /*timeout_msec=*/-1, cancellable_,
                    reinterpret_cast<GAsyncReadyCallback>(OnAccessResponse),
                    this);
}

// static
void CameraPortalPrivate::OnAccessResponse(GDBusProxy* proxy,
                                           GAsyncResult* result,
                                           gpointer user_data) {
  CameraPortalPrivate* that = static_cast<CameraPortalPrivate*>(user_data);
  RTC_DCHECK(that);

  Scoped<GError> error;
  Scoped<GVariant> variant(
      g_dbus_proxy_call_finish(proxy, result, error.receive()));
  if (!variant) {
    if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
      return;
    RTC_LOG(LS_ERROR) << "Failed to access portal:" << error->message;
    if (that->access_request_signal_id_) {
      g_dbus_connection_signal_unsubscribe(that->connection_,
                                           that->access_request_signal_id_);
      that->access_request_signal_id_ = 0;
    }
    that->OnPortalDone(RequestResponse::kError);
  }
}

// static
void CameraPortalPrivate::OnResponseSignalEmitted(GDBusConnection* connection,
                                                  const char* sender_name,
                                                  const char* object_path,
                                                  const char* interface_name,
                                                  const char* signal_name,
                                                  GVariant* parameters,
                                                  gpointer user_data) {
  CameraPortalPrivate* that = static_cast<CameraPortalPrivate*>(user_data);
  RTC_DCHECK(that);

  uint32_t portal_response;
  g_variant_get(parameters, "(u@a{sv})", &portal_response, nullptr);
  if (portal_response) {
    RTC_LOG(LS_INFO) << "Camera access denied by the XDG portal.";
    that->OnPortalDone(RequestResponseFromPortalResponse(portal_response));
    return;
  }

  RTC_LOG(LS_VERBOSE) << "Camera access granted by the XDG portal.";

  GVariantBuilder builder;
  g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);

  g_dbus_proxy_call(
      that->proxy_, "OpenPipeWireRemote", g_variant_new("(a{sv})", &builder),
      G_DBUS_CALL_FLAGS_NONE, /*timeout_msec=*/-1, that->cancellable_,
      reinterpret_cast<GAsyncReadyCallback>(OnOpenResponse), that);
}

void CameraPortalPrivate::OnOpenResponse(GDBusProxy* proxy,
                                         GAsyncResult* result,
                                         gpointer user_data) {
  CameraPortalPrivate* that = static_cast<CameraPortalPrivate*>(user_data);
  RTC_DCHECK(that);

  Scoped<GError> error;
  Scoped<GUnixFDList> outlist;
  Scoped<GVariant> variant(g_dbus_proxy_call_with_unix_fd_list_finish(
      proxy, outlist.receive(), result, error.receive()));
  if (!variant) {
    if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
      return;
    RTC_LOG(LS_ERROR) << "Failed to open PipeWire remote:" << error->message;
    if (that->access_request_signal_id_) {
      g_dbus_connection_signal_unsubscribe(that->connection_,
                                           that->access_request_signal_id_);
      that->access_request_signal_id_ = 0;
    }
    that->OnPortalDone(RequestResponse::kError);
    return;
  }

  int32_t index;
  g_variant_get(variant.get(), "(h)", &index);

  int fd = g_unix_fd_list_get(outlist.get(), index, error.receive());

  if (fd == kInvalidPipeWireFd) {
    RTC_LOG(LS_ERROR) << "Failed to get file descriptor from the list: "
                      << error->message;
    that->OnPortalDone(RequestResponse::kError);
    return;
  }

  that->OnPortalDone(RequestResponse::kSuccess, fd);
}

void CameraPortalPrivate::OnPortalDone(RequestResponse result, int fd) {
  notifier_->OnCameraRequestResult(result, fd);
}

CameraPortal::CameraPortal(PortalNotifier* notifier)
    : private_(std::make_unique<CameraPortalPrivate>(notifier)) {}

CameraPortal::~CameraPortal() {}

void CameraPortal::Start() {
  private_->Start();
}

}  // namespace webrtc
