gboolean
flatpak_builtin_document_info (int argc, char **argv,
                               GCancellable *cancellable,
                               GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GDBusConnection) session_bus = NULL;
  const char *file;
  XdpDbusDocuments *documents;
  g_autofree char *mountpoint = NULL;
  g_autofree char *basename = NULL;
  g_autofree char *doc_id = NULL;
  g_autofree char *doc_path = NULL;
  g_autofree char *origin = NULL;
  const char *app_id;
  const char **perms;
  g_autoptr(GVariant) apps = NULL;
  g_autoptr(GVariantIter) iter = NULL;

  context = g_option_context_new (_("FILE - Get information about an exported file"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_NO_DIR,
                                     NULL, cancellable, error))
    return FALSE;

  if (argc < 2)
    return usage_error (context, _("FILE must be specified"), error);

  file = argv[1];
  basename = g_path_get_basename (file);

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
  if (session_bus == NULL)
    return FALSE;

  documents = xdp_dbus_documents_proxy_new_sync (session_bus, 0,
                                                 "org.freedesktop.portal.Documents",
                                                 "/org/freedesktop/portal/documents",
                                                 NULL, error);
  if (documents == NULL)
    return FALSE;

  if (!xdp_dbus_documents_call_get_mount_point_sync (documents, &mountpoint,
                                                     NULL, error))
    return FALSE;

  if (!xdp_dbus_documents_call_lookup_sync (documents, file, &doc_id, NULL, error))
    return FALSE;

  if (strcmp (doc_id, "") == 0)
    {
      g_print (_("Not exported\n"));
      return TRUE;
    }

  doc_path = g_build_filename (mountpoint, doc_id, basename, NULL);

  if (!xdp_dbus_documents_call_info_sync (documents, doc_id, &origin, &apps,
                                          NULL, error))
    return FALSE;

  iter = g_variant_iter_new (apps);

  g_print ("id: %s\n", doc_id);
  g_print ("path: %s\n", doc_path);
  g_print ("origin: %s\n", origin);
  if (g_variant_iter_n_children (iter) > 0)
    g_print ("permissions:\n");
  while (g_variant_iter_next (iter, "{&s^a&s}", &app_id, &perms))
    {
      int i;
      g_print ("\t%s\t", app_id);
      for (i = 0; perms[i]; i++)
        {
          if (i > 0)
            g_print (", ");
          g_print ("%s", perms[i]);
        }
      g_print ("\n");
    }

  return TRUE;
}
static gboolean
print_documents (const char *app_id,
                 Column *columns,
                 GCancellable *cancellable,
                 GError **error)
{
  g_autoptr(GDBusConnection) session_bus = NULL;
  XdpDbusDocuments *documents;
  g_autoptr(GVariant) apps = NULL;
  g_autoptr(GVariantIter) iter = NULL;
  const char *id;
  const char *origin;
  FlatpakTablePrinter *printer;
  g_autofree char *mountpoint = NULL;
  gboolean need_perms = FALSE;
  int i;

  if (columns[0].name == NULL)
    return TRUE;

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
  if (session_bus == NULL)
    return FALSE;

  documents = xdp_dbus_documents_proxy_new_sync (session_bus, 0,
                                                 "org.freedesktop.portal.Documents",
                                                 "/org/freedesktop/portal/documents",
                                                 NULL, error);

  if (documents == NULL)
    return FALSE;

  if (!xdp_dbus_documents_call_list_sync (documents, app_id ? app_id : "", &apps, NULL, error))
    return FALSE;

  if (!xdp_dbus_documents_call_get_mount_point_sync (documents, &mountpoint, NULL, error))
    return FALSE;

  printer = flatpak_table_printer_new ();
  flatpak_table_printer_set_columns (printer, columns);
  for (i = 0; columns[i].name; i++)
    {
      if (strcmp (columns[i].name, "permissions") == 0 ||
          strcmp (columns[i].name, "application") == 0)
        {
          need_perms = TRUE;
          break;
        }
    }

  iter = g_variant_iter_new (apps);
  while (g_variant_iter_next (iter, "{&s^&ay}", &id, &origin))
    {
      g_autoptr(GVariant) apps2 = NULL;
      g_autoptr(GVariantIter) iter2 = NULL;
      const char *app_id2 = NULL;
      const char **perms = NULL;
      gboolean just_perms = FALSE;

      if (need_perms)
        {
          g_autofree char *origin2 = NULL;
          if (!xdp_dbus_documents_call_info_sync (documents, id, &origin2, &apps2, NULL, error))
            return FALSE;
          iter2 = g_variant_iter_new (apps2);
        }

      while ((iter2 && g_variant_iter_next (iter2, "{&s^a&s}", &app_id2, &perms)) || !just_perms)
        {
          for (i = 0; columns[i].name; i++)
            {
              if (strcmp (columns[i].name, "application") == 0)
                flatpak_table_printer_add_column (printer, app_id2);
              else if (strcmp (columns[i].name, "permissions") == 0)
                {
                  g_autofree char *value = NULL;
                  if (perms)
                    value = g_strjoinv (" ", (char **)perms);
                  flatpak_table_printer_add_column (printer, value);
                }
              else if (just_perms)
                flatpak_table_printer_add_column (printer, "");
              else if (strcmp (columns[i].name, "id") == 0)
                flatpak_table_printer_add_column (printer, id);
              else if (strcmp (columns[i].name, "origin") == 0)
                flatpak_table_printer_add_column (printer, origin);
              else if (strcmp (columns[i].name, "path") == 0)
                {
                  g_autofree char *basename = g_path_get_basename (origin);
                  g_autofree char *path = g_build_filename (mountpoint, id, basename, NULL);
                  flatpak_table_printer_add_column (printer, path);
                }
            }

          flatpak_table_printer_finish_row (printer);

          just_perms = TRUE;
        }
    }

  flatpak_table_printer_print (printer);
  flatpak_table_printer_free (printer);

  return TRUE;
}